diff --git a/docs/changelog.md b/docs/changelog.md index 6374d80c..9c7f984e 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -8,6 +8,9 @@ Requires libvips v8.7.0. * Input image decoding now fails fast, set `failOnError` to change this behaviour. +* Failed filesystem-based input now separates missing file and invalid format errors. + [#1542](https://github.com/lovell/sharp/issues/1542) + #### v0.21.2 - 13th January 2019 * Ensure all metadata is removed from PNG output unless `withMetadata` used. diff --git a/lib/output.js b/lib/output.js index 40ad4d0f..3fff4a9b 100644 --- a/lib/output.js +++ b/lib/output.js @@ -32,7 +32,7 @@ const sharp = require('../build/Release/sharp.node'); */ function toFile (fileOut, callback) { if (!fileOut || fileOut.length === 0) { - const errOutputInvalid = new Error('Invalid output'); + const errOutputInvalid = new Error('Missing output file path'); if (is.fn(callback)) { callback(errOutputInvalid); } else { diff --git a/src/common.cc b/src/common.cc index c4b301b6..7b7c01ad 100644 --- a/src/common.cc +++ b/src/common.cc @@ -137,6 +137,7 @@ namespace sharp { case ImageType::VIPS: id = "v"; break; case ImageType::RAW: id = "raw"; break; case ImageType::UNKNOWN: id = "unknown"; break; + case ImageType::MISSING: id = "missing"; break; } return id; } @@ -203,6 +204,10 @@ namespace sharp { } else if (EndsWith(loader, "Magick") || EndsWith(loader, "MagickFile")) { imageType = ImageType::MAGICK; } + } else { + if (EndsWith(vips::VError().what(), " not found\n")) { + imageType = ImageType::MISSING; + } } return imageType; } @@ -269,6 +274,9 @@ namespace sharp { } else { // From filesystem imageType = DetermineImageType(descriptor->file.data()); + if (imageType == ImageType::MISSING) { + throw vips::VError("Input file is missing"); + } if (imageType != ImageType::UNKNOWN) { try { vips::VOption *option = VImage::option() @@ -291,7 +299,7 @@ namespace sharp { throw vips::VError(std::string("Input file has corrupt header: ") + err.what()); } } else { - throw vips::VError("Input file is missing or of an unsupported image format"); + throw vips::VError("Input file contains unsupported image format"); } } } diff --git a/src/common.h b/src/common.h index 91e1bd9b..210558d3 100644 --- a/src/common.h +++ b/src/common.h @@ -106,7 +106,8 @@ namespace sharp { FITS, VIPS, RAW, - UNKNOWN + UNKNOWN, + MISSING }; // How many tasks are in the queue? diff --git a/test/unit/io.js b/test/unit/io.js index 130ab0ea..eb4d05dd 100644 --- a/test/unit/io.js +++ b/test/unit/io.js @@ -263,7 +263,8 @@ describe('Input/output', function () { it('Fail when output File is input File', function (done) { sharp(fixtures.inputJpg).toFile(fixtures.inputJpg, function (err) { - assert(!!err); + assert(err instanceof Error); + assert.strictEqual('Cannot use same file for input and output', err.message); done(); }); }); @@ -273,14 +274,16 @@ describe('Input/output', function () { assert(false); done(); }).catch(function (err) { - assert(!!err); + assert(err instanceof Error); + assert.strictEqual('Cannot use same file for input and output', err.message); done(); }); }); it('Fail when output File is empty', function (done) { sharp(fixtures.inputJpg).toFile('', function (err) { - assert(!!err); + assert(err instanceof Error); + assert.strictEqual('Missing output file path', err.message); done(); }); }); @@ -290,7 +293,8 @@ describe('Input/output', function () { assert(false); done(); }).catch(function (err) { - assert(!!err); + assert(err instanceof Error); + assert.strictEqual('Missing output file path', err.message); done(); }); }); @@ -301,6 +305,7 @@ describe('Input/output', function () { done(); }).catch(function (err) { assert(err instanceof Error); + assert.strictEqual('Input buffer contains unsupported image format', err.message); done(); }); }); @@ -311,6 +316,18 @@ describe('Input/output', function () { done(); }).catch(function (err) { assert(err instanceof Error); + assert.strictEqual('Input buffer contains unsupported image format', err.message); + done(); + }); + }); + + it('Fail when input file path is missing', function (done) { + sharp('does-not-exist').toBuffer().then(function () { + assert(false); + done(); + }).catch(function (err) { + assert(err instanceof Error); + assert.strictEqual('Input file is missing', err.message); done(); }); });