Skip to content
This repository was archived by the owner on May 22, 2025. It is now read-only.

Commit 9f492c3

Browse files
authored
Merge pull request #697 from rhodgkins/stream-errors
Exposed stream errors to error event
2 parents 3c293f5 + c6ea17e commit 9f492c3

File tree

3 files changed

+92
-6
lines changed

3 files changed

+92
-6
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -848,6 +848,8 @@ ffmpeg('/path/to/file.avi')
848848

849849
The `error` event is emitted when an error occurs when running ffmpeg or when preparing its execution. It is emitted with an error object as an argument. If the error happened during ffmpeg execution, listeners will also receive two additional arguments containing ffmpegs stdout and stderr.
850850

851+
If streams are used for input or output, any errors emitted from these streams will be passed through to this event, attached to the `error` as `inputStreamError` and `outputStreamError` for input and output streams respectively.
852+
851853
**Warning**: you should _always_ set a handler for the `error` event, as node's default behaviour when an `error` event without any listeners is emitted is to output the error to the console and _terminate the program_.
852854

853855
```js

lib/processor.js

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ module.exports = function(proto) {
7171
* Emitted when an error happens when preparing or running a command
7272
*
7373
* @event FfmpegCommand#error
74-
* @param {Error} error error object
74+
* @param {Error} error error object, with optional properties 'inputStreamError' / 'outputStreamError' for errors on their respective streams
7575
* @param {String|null} stdout ffmpeg stdout, unless outputting to a stream
7676
* @param {String|null} stderr ffmpeg stderr
7777
*/
@@ -444,7 +444,9 @@ module.exports = function(proto) {
444444
// Pipe input stream if any
445445
if (inputStream) {
446446
inputStream.source.on('error', function(err) {
447-
emitEnd(new Error('Input stream error: ' + err.message));
447+
var reportingErr = new Error('Input stream error: ' + err.message);
448+
reportingErr.inputStreamError = err;
449+
emitEnd(reportingErr);
448450
ffmpegProc.kill();
449451
});
450452

@@ -474,7 +476,7 @@ module.exports = function(proto) {
474476

475477
// Handle output stream events
476478
outputStream.target.on('close', function() {
477-
self.logger.debug('Output stream closed, scheduling kill for ffmpgeg process');
479+
self.logger.debug('Output stream closed, scheduling kill for ffmpeg process');
478480

479481
// Don't kill process yet, to give a chance to ffmpeg to
480482
// terminate successfully first This is necessary because
@@ -487,9 +489,11 @@ module.exports = function(proto) {
487489
});
488490

489491
outputStream.target.on('error', function(err) {
490-
self.logger.debug('Output stream error, killing ffmpgeg process');
491-
emitEnd(new Error('Output stream error: ' + err.message), stdoutRing.get(), stderrRing.get());
492-
ffmpegProc.kill();
492+
self.logger.debug('Output stream error, killing ffmpeg process');
493+
var reportingErr = new Error('Output stream error: ' + err.message);
494+
reportingErr.outputStreamError = err;
495+
emitEnd(reportingErr, stdoutRing.get(), stderrRing.get());
496+
ffmpegProc.kill('SIGKILL');
493497
});
494498
}
495499

test/processor.test.js

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -770,6 +770,48 @@ describe('Processor', function() {
770770
})
771771
.saveToFile(testFile);
772772
});
773+
774+
it('should pass input stream errors through to error handler', function(done) {
775+
var testFile = path.join(__dirname, 'assets', 'testConvertFromStream.avi')
776+
777+
const readError = new Error('Read Error')
778+
const instream = new (require('stream').Readable)({
779+
read() {
780+
process.nextTick(() => this.emit('error', readError))
781+
}
782+
})
783+
784+
const command = this.getCommand({ source: instream, logger: testhelper.logger })
785+
786+
let startCalled = false
787+
const self = this
788+
789+
command
790+
.usingPreset('divx')
791+
.on('start', function() {
792+
startCalled = true
793+
command.ffmpegProc.on('exit', function() {
794+
fs.exists(testFile, (exists) => {
795+
exists.should.be.false()
796+
done()
797+
})
798+
})
799+
})
800+
.on('error', function(err, stdout, stderr) {
801+
self.saveOutput(stdout, stderr)
802+
startCalled.should.be.true()
803+
assert.ok(err)
804+
err.message.indexOf('Input stream error: ').should.equal(0)
805+
assert.strictEqual(err.inputStreamError, readError)
806+
})
807+
.on('end', function(stdout, stderr) {
808+
testhelper.logOutput(stdout, stderr)
809+
console.log('end was called, expected a error')
810+
assert.ok(false)
811+
done()
812+
})
813+
.saveToFile(testFile)
814+
})
773815
});
774816

775817
describe('mergeToFile', function() {
@@ -911,6 +953,44 @@ describe('Processor', function() {
911953
new FfmpegCommand().writeToStream({end: true});
912954
}).should.throw(/PassThrough stream is not supported on node v0.8/);
913955
});
956+
957+
it('should pass output stream errors through to error handler', function(done) {
958+
959+
const writeError = new Error('Write Error')
960+
const outstream = new (require('stream').Writable)({
961+
write(chunk, encoding, callback) {
962+
callback(writeError)
963+
}
964+
})
965+
966+
const command = this.getCommand({ source: this.testfile, logger: testhelper.logger })
967+
968+
let startCalled = false
969+
const self = this
970+
971+
command
972+
.usingPreset('divx')
973+
.on('start', function() {
974+
startCalled = true
975+
command.ffmpegProc.on('exit', function() {
976+
done()
977+
})
978+
})
979+
.on('error', function(err, stdout, stderr) {
980+
self.saveOutput(stdout, stderr)
981+
startCalled.should.be.true()
982+
assert.ok(err)
983+
err.message.indexOf('Output stream error: ').should.equal(0)
984+
assert.strictEqual(err.outputStreamError, writeError)
985+
})
986+
.on('end', function(stdout, stderr) {
987+
console.log('end was called, expected a error')
988+
testhelper.logOutput(stdout, stderr)
989+
assert.ok(false)
990+
done()
991+
})
992+
.writeToStream(outstream)
993+
})
914994
});
915995

916996
describe('Outputs', function() {

0 commit comments

Comments
 (0)