1

In my app, I need to spawn a debugger process given a dump file to debug, say "example.dmp". If the dump file is not found or not it is not a dump file. The process will be successfully spawned but it will exit immediately. I would like to throw an error message in an async function which can be try catched later.

    const spawnDebuggerProcess = (debuggerConfigs) => {
        let debuggerProcess = spawn(config.debuggerName, debuggerConfigs)

        debuggerProcess.on('exit', (code, signal) => {
            console.log('pid ' + `${debuggerProcess.pid}`)
            console.log('child process exited with ' + `code ${code} and signal ${signal}`)
        })

        debuggerProcess.on('error', (error) => {})

        if (debuggerProcess.pid !== undefined) {
            return debuggerProcess
        }

        throw externalError.createError({
            name: externalError.SPAWN_DEBUGGER_PROCESS_ERROR,
            description: 'Failed to spawn debugging process'
        })
    }

One of my thought is to time give this function a time window before returning. If the process exited before the time window I should throw an error. But since node.js is async. I don't have an idea of how can this be realized. Thanks!

==== EDIT =====

   const spawnDebuggerProcess = async (debuggerConfigs) => {
        let debuggerProcess = spawn(config.debuggerProcess.debuggerName, debuggerConfigs)

        /** added a flag */
        let exited = false

        debuggerProcess.on('exit', (code, signal) => {
            console.log('pid ' + `${debuggerProcess.pid}`)
            console.log('child process exited with ' + `code ${code} and signal ${signal}`)

            /** set flag to true if exited */
            exited = true
        })

        debuggerProcess.on('error', (error) => {})

        if (debuggerProcess.pid !== undefined) {

            /** delay this promise for a certain amount of time, act as the time window */
            await delay(config.debuggerProcess.immediateExitDelay)
            /** check the flag */
            if (exited) {
                throw externalError.createError({
                    name: externalError.SPAWN_DEBUGGER_PROCESS_ERROR,
                    description: 'Process exited immediately'
                })
            }

            return debuggerProcess
        }

        throw externalError.createError({
            name: externalError.SPAWN_DEBUGGER_PROCESS_ERROR,
            description: 'Failed to spawn debugging process'
        })
    }

It seems to be working, but I am not sure if it is a good practice.

Rui
  • 249
  • 2
  • 4
  • 10
  • 1
    Doesn't the debugger process exit in those situations with a particular exit code that you can check for? – robertklep Aug 01 '17 at 18:24
  • You are absolutely right, but first, on the windows system there are might be a lot of different exit codes, secondly, if I throw an error in the callback function of the "exit" event, it cannot be "try catched". – Rui Aug 01 '17 at 22:33
  • 1
    The issue is that you want the `spawnDebuggerProcess` function to return the `debuggerProcess` _or_, at some point in the future, throw an error if the process didn't run long enough. You can't do both at the same time. – robertklep Aug 02 '17 at 06:37
  • But I can delay the promise to return the `debuggerProcess` right? If the program didn't exit within the delay windows, I return the child_process, otherwise throw an error. Is there a problem with my approach? – Rui Aug 02 '17 at 17:10
  • 1
    Yes, to be fair, the code that you're showing will work, but it's not good practice (in particular, handling the `exit` event and setting the `exited` variable). However, I can't really suggest an alternative because of the way your code is structured and lacking context (for instance, what the return value of `spawnDebuggerProcess` is being used for). – robertklep Aug 02 '17 at 18:55
  • So basically I want the `spawnDebuggerProcess` function to spawn a `child_process` and return the `child_process` object on success otherwise throw an error which CAN BE CAUGHT. There are two failure scenarios, first, the child process failed to start, second, the child process exited immediately after starting. Later on the `debuggerProcess` will be saved to a hashmap, therefore if I want to kill the process I have its `pid` saved. What do you suggest on implementing the same functionality? – Rui Aug 02 '17 at 21:10
  • 1
    It's tricky, especially if you want the ability to catch a "did not run for long enough" exception. In that case, I can't think of an easy alternative to your own code. I would perhaps consider using RxJS or a simple event emitter, but that moves the burden of handling any startup errors to somewhere in the future (as opposed to being able to catch it "immediately"). – robertklep Aug 03 '17 at 06:29
  • Do you mind elaborate a little bit more on why isn't it a good idea to set the flag in the callback? – Rui Aug 03 '17 at 18:19
  • I wouldn't necessarily say it's not a good idea, it just doesn't _feel_ right (it's like using global variables). – robertklep Aug 03 '17 at 18:31

0 Answers0