mirror of
https://github.com/atom/atom.git
synced 2026-04-06 03:02:13 -04:00
Merge pull request #4531 from atom/bo-buffered-process-error
Better BufferedProcess error handling
This commit is contained in:
42
spec/buffered-process-spec.coffee
Normal file
42
spec/buffered-process-spec.coffee
Normal file
@@ -0,0 +1,42 @@
|
||||
BufferedProcess = require '../src/buffered-process'
|
||||
|
||||
describe "BufferedProcess", ->
|
||||
describe "when a bad command is specified", ->
|
||||
[oldOnError] = []
|
||||
beforeEach ->
|
||||
oldOnError = window.onerror
|
||||
window.onerror = jasmine.createSpy()
|
||||
|
||||
afterEach ->
|
||||
window.onerror = oldOnError
|
||||
|
||||
describe "when there is an error handler specified", ->
|
||||
it "calls the error handler and does not throw an exception", ->
|
||||
process = new BufferedProcess
|
||||
command: 'bad-command-nope'
|
||||
args: ['nothing']
|
||||
options: {}
|
||||
|
||||
errorSpy = jasmine.createSpy().andCallFake (error) -> error.handle()
|
||||
process.onWillThrowError(errorSpy)
|
||||
|
||||
waitsFor -> errorSpy.callCount > 0
|
||||
|
||||
runs ->
|
||||
expect(window.onerror).not.toHaveBeenCalled()
|
||||
expect(errorSpy).toHaveBeenCalled()
|
||||
expect(errorSpy.mostRecentCall.args[0].error.message).toContain 'spawn bad-command-nope ENOENT'
|
||||
|
||||
describe "when there is not an error handler specified", ->
|
||||
it "calls the error handler and does not throw an exception", ->
|
||||
process = new BufferedProcess
|
||||
command: 'bad-command-nope'
|
||||
args: ['nothing']
|
||||
options: {}
|
||||
|
||||
waitsFor -> window.onerror.callCount > 0
|
||||
|
||||
runs ->
|
||||
expect(window.onerror).toHaveBeenCalled()
|
||||
expect(window.onerror.mostRecentCall.args[0]).toContain 'Failed to spawn command `bad-command-nope`'
|
||||
expect(window.onerror.mostRecentCall.args[4].name).toBe 'BufferedProcessError'
|
||||
@@ -1,5 +1,6 @@
|
||||
_ = require 'underscore-plus'
|
||||
ChildProcess = require 'child_process'
|
||||
{Emitter} = require 'event-kit'
|
||||
|
||||
# Extended: A wrapper which provides standard error/output line buffering for
|
||||
# Node's ChildProcess.
|
||||
@@ -17,6 +18,10 @@ ChildProcess = require 'child_process'
|
||||
# ```
|
||||
module.exports =
|
||||
class BufferedProcess
|
||||
###
|
||||
Section: Construction
|
||||
###
|
||||
|
||||
# Public: Runs the given command by spawning a new child process.
|
||||
#
|
||||
# * `options` An {Object} with the following keys:
|
||||
@@ -39,6 +44,7 @@ class BufferedProcess
|
||||
# * `exit` The callback {Function} which receives a single argument
|
||||
# containing the exit status (optional).
|
||||
constructor: ({command, args, options, stdout, stderr, exit}={}) ->
|
||||
@emitter = new Emitter
|
||||
options ?= {}
|
||||
# Related to joyent/node#2318
|
||||
if process.platform is "win32"
|
||||
@@ -94,6 +100,41 @@ class BufferedProcess
|
||||
processExited = true
|
||||
triggerExitCallback()
|
||||
|
||||
@process.on 'error', (error) =>
|
||||
handled = false
|
||||
handle = -> handled = true
|
||||
|
||||
@emitter.emit 'will-throw-error', {error, handle}
|
||||
|
||||
if error.code is 'ENOENT' and error.syscall.indexOf('spawn') is 0
|
||||
error = new Error("Failed to spawn command `#{command}`. Make sure `#{command}` is installed and on your PATH", error.path)
|
||||
error.name = 'BufferedProcessError'
|
||||
|
||||
throw error unless handled
|
||||
|
||||
###
|
||||
Section: Event Subscription
|
||||
###
|
||||
|
||||
# Public: Will call your callback when an error will be raised by the process.
|
||||
# Usually this is due to the command not being available or not on the PATH.
|
||||
# You can call `handle()` on the object passed to your callback to indicate
|
||||
# that you have handled this error.
|
||||
#
|
||||
# * `callback` {Function} callback
|
||||
# * `errorObject` {Object}
|
||||
# * `error` {Object} the error object
|
||||
# * `handle` {Function} call this to indicate you have handled the error.
|
||||
# The error will not be thrown if this function is called.
|
||||
#
|
||||
# Returns a {Disposable}
|
||||
onWillThrowError: (callback) ->
|
||||
@emitter.on 'will-throw-error', callback
|
||||
|
||||
###
|
||||
Section: Helper Methods
|
||||
###
|
||||
|
||||
# Helper method to pass data line by line.
|
||||
#
|
||||
# * `stream` The Stream to read from.
|
||||
|
||||
Reference in New Issue
Block a user