GTF
GTF

Reputation: 8385

why can't I catch these errors?

I'm writing a test suite for a library, and trying to repeat a pattern I have used literally everywhere else in order to test for the errors it should throw. For example, in another test suite I have the following code (which works perfectly):

const fun = rawFileDownloaderFactory(fetch)(noop);
await expect(() => fun(t)).rejects.toThrow(new NoDirectoryAccessError(badDir));

I am now testing to see if my function throws when it can't write to a file (this is a different part of the library) but somehow the error gets thrown outside any of the error handling logic. In order to get to the bottom of this I wrote the following harness:

const fun = datafileWriterFactory(fetch)(selector, parser)(noop);
try {
  console.log("START");
  await (
    fun(t)
    .then(() => console.log("WORKED"))
    .catch((e) => console.error("FAILED", e))
  );
} catch(e) {
  console.error("This should have been caught before", e);
} finally {
  console.log("FINISH");
}
await expect(() => fun(t)).rejects.toThrow();

I'm using jest as my test runner, and when I run this test I get the following output:

● Console

    console.log
      START

      at Object.<anonymous> (lib/sinks/datafile_writer_factory.test.ts:256:15)

  ● datafileWriterFactory creates a Sink which › throws when it cannot write to the file

    ENOENT: no such file or directory, open '/tmp/knobble-test-FHlzW9-not/addresses.json'

I would have expected, however, at least one of the error handling methods to work (either try ... catch or Promise.catch).

Why might these errors (being thrown by fs.createWriteStream) not be caught properly within jest?

Upvotes: 0

Views: 120

Answers (1)

I think your code doesn't execute your catch block nor the catch callback because the fs.createWriteStream method returns a WritableStream instead of a Promise which resolves to the WritableStream.

This means that you'd need to listen for an error event instead of trying to handle a Promise rejection or catch an error.

I've tried this in the console to confirm:

const fs = require("fs");

let writeStream;

try {
  writeStream = fs.createWriteStream("/test.txt");
} catch (e) {
  console.log("not logged", e);
}

writeStream.on("error", (e) => console.log("logged", e));

Assuming I can't write to /test.txt, for example, I get:

$ node repro.js

logged { [Error: EROFS: read-only file system, open '/test.txt'] errno: -30, code: 'EROFS', syscall: 'open', path: '/test.txt' }

Upvotes: 1

Related Questions