@@ -12,9 +12,11 @@ import {
1212 ConnectionError ,
1313 EmptyLangsResponseError ,
1414 ForbiddenError ,
15+ InitializationError ,
1516 InvalidTokenError ,
1617 ObsoleteClientError ,
1718 RuntimeError ,
19+ SpawnError ,
1820} from "../errors" ;
1921import {
2022 CliOutput ,
@@ -261,45 +263,59 @@ export default class TMC {
261263 exercisePath : string ,
262264 pythonExecutablePath ?: string ,
263265 progressCallback ?: ( progressPct : number , message ?: string ) => void ,
264- ) : [ Promise < Result < RunResult , BaseError > > , ( ) => void ] {
266+ ) : {
267+ process : Promise < Result < RunResult , BaseError | InitializationError > > ;
268+ interrupt : ( ) => void ;
269+ } {
265270 const env : { [ key : string ] : string } = { } ;
266271 if ( pythonExecutablePath ) {
267272 env . TMC_LANGS_PYTHON_EXEC = pythonExecutablePath ;
268273 }
269- const { interrupt , result } = this . _spawnLangsProcess ( {
274+ const process = this . _spawnLangsProcess ( {
270275 args : [ "run-tests" , "--exercise-path" , exercisePath ] ,
271276 env,
272277 onStdout : ( data ) =>
273278 progressCallback ?.( 100 * data [ "percent-done" ] , data . message ?? undefined ) ,
274279 onStderr : ( data ) => Logger . info ( "Rust Langs" , data ) ,
275280 processTimeout : CLI_PROCESS_TIMEOUT ,
276281 } ) ;
282+ if ( process . err ) {
283+ return { process : Promise . resolve ( process ) , interrupt : ( ) : void => { } } ;
284+ }
285+ const { interrupt, result } = process . val ;
277286 const postResult = result . then ( ( res ) =>
278287 res
279288 . andThen ( ( x ) => this . _checkLangsResponse ( x , "test-result" ) )
280289 . map ( ( x ) => x . data [ "output-data" ] ) ,
281290 ) ;
282291
283- return [ postResult , interrupt ] ;
292+ return { process : postResult , interrupt } ;
284293 }
285294
286295 public runCheckstyle (
287296 exercisePath : string ,
288297 progressCallback ?: ( progressPct : number , message ?: string ) => void ,
289- ) : [ Promise < Result < StyleValidationResult | null , BaseError > > , ( ) => void ] {
290- const { interrupt, result } = this . _spawnLangsProcess ( {
298+ ) : {
299+ process : Promise < Result < StyleValidationResult | null , BaseError > > ;
300+ interrupt : ( ) => void ;
301+ } {
302+ const process = this . _spawnLangsProcess ( {
291303 args : [ "checkstyle" , "--locale" , "en" , "--exercise-path" , exercisePath ] ,
292304 onStdout : ( data ) =>
293305 progressCallback ?.( 100 * data [ "percent-done" ] , data . message ?? undefined ) ,
294306 onStderr : ( data ) => Logger . info ( "Rust Langs" , data ) ,
295307 processTimeout : CLI_PROCESS_TIMEOUT ,
296308 } ) ;
309+ if ( process . err ) {
310+ return { process : Promise . resolve ( process ) , interrupt : ( ) : void => { } } ;
311+ }
312+ const { interrupt, result } = process . val ;
297313 const checkstyleResult = result . then ( ( res ) =>
298314 res
299315 . andThen ( ( x ) => this . _checkLangsResponse ( x , "validation" ) )
300316 . map ( ( x ) => x . data [ "output-data" ] ) ,
301317 ) ;
302- return [ checkstyleResult , interrupt ] ;
318+ return { process : checkstyleResult , interrupt } ;
303319 }
304320
305321 // ---------------------------------------------------------------------------------------------
@@ -946,7 +962,11 @@ export default class TMC {
946962 }
947963 }
948964
949- const res = await this . _spawnLangsProcess ( langsArgs ) . result ;
965+ const process = this . _spawnLangsProcess ( langsArgs ) ;
966+ if ( process . err ) {
967+ return process ;
968+ }
969+ const res = await process . val . result ;
950970 return res
951971 . andThen ( ( x ) => this . _checkLangsResponse ( x , outputDataKind ) )
952972 . andThen ( ( x ) => {
@@ -1020,7 +1040,9 @@ export default class TMC {
10201040 *
10211041 * @returns Rust process runner.
10221042 */
1023- private _spawnLangsProcess ( commandArgs : LangsProcessArgs ) : LangsProcessRunner {
1043+ private _spawnLangsProcess (
1044+ commandArgs : LangsProcessArgs ,
1045+ ) : Result < LangsProcessRunner , InitializationError | SpawnError > {
10241046 const { args, env, obfuscate, onStderr, onStdout, stdin, processTimeout } = commandArgs ;
10251047
10261048 let theResult : OutputData | undefined ;
@@ -1044,16 +1066,21 @@ export default class TMC {
10441066
10451067 let active = true ;
10461068 let interrupted = false ;
1047- const cprocess = cp . spawn ( this . cliPath , args , {
1048- env : {
1049- ...process . env ,
1050- ...env ,
1051- RUST_LOG : "debug,rustls=warn,reqwest=warn" ,
1052- TMC_LANGS_TMC_ROOT_URL : tmcBackendUrl ,
1053- TMC_LANGS_MOOC_ROOT_URL : moocBackendUrl ,
1054- TMC_LANGS_CONFIG_DIR : tmcLangsConfigDir ,
1055- } ,
1056- } ) ;
1069+ let cprocess ;
1070+ try {
1071+ cprocess = cp . spawn ( this . cliPath , args , {
1072+ env : {
1073+ ...process . env ,
1074+ ...env ,
1075+ RUST_LOG : "debug,rustls=warn,reqwest=warn" ,
1076+ TMC_LANGS_TMC_ROOT_URL : tmcBackendUrl ,
1077+ TMC_LANGS_MOOC_ROOT_URL : moocBackendUrl ,
1078+ TMC_LANGS_CONFIG_DIR : tmcLangsConfigDir ,
1079+ } ,
1080+ } ) ;
1081+ } catch ( error ) {
1082+ return Err ( new SpawnError ( error , "Failed to run tmc-langs-cli" ) ) ;
1083+ }
10571084 if ( stdin ) {
10581085 cprocess . stdin . write ( stdin + "\n" ) ;
10591086 }
@@ -1190,7 +1217,8 @@ ${error.message}`;
11901217 kill ( cprocess . pid as number ) ;
11911218 }
11921219 } ;
1193- return { interrupt, result } ;
1220+ const res = { interrupt, result } ;
1221+ return Ok ( res ) ;
11941222 }
11951223}
11961224
0 commit comments