When using supertest to test an express app together with the example in the readme from https://github.com/davidbanham/express-async-errors, it seems supertest will not properly invoke the error handling middleware, and thus the test just times out rather than actually responding with the logic defined in the error handler.
This behaviour works when invoking the code via HTTP.
Same issue with https://www.npmjs.com/package/co-router
Basically if the route doesn't handle the error and the app's error middleware does, that error is never caught by supertest.
~Not sure if https://github.com/visionmedia/supertest/pull/402 would help here.~ It does not.
@NinnOgTonic @knownasilya Do you have a reproduction case to take a look? I just tried to run all tests from https://github.com/davidbanham/express-async-errors and didn't get any errors.
@jonathansamines Please view the following repository, i have written the source in TS, but also included the transpiled JS for the reproduction: https://github.com/NinnOgTonic/supertest-bug
I am experiencing this too... anyone have a workaround?
@NinnOgTonic Sorry for the super-late response. I just checked your example, and the issue is not on supertest, but in express. Express doesn't know how to handle async/await nor promises by default. You have to forward any errors by either using .catch or a try/catch statement to the express next handler.
@osdiab Can you check, if you are experiencing the same issue as @NinnOgTonic ? If that is not the case, please provide a reproduction example.
My code is using Koa so sounds like probably not the same as his.
I have an error middleware that does roughly the following
try { next() } catch (err) { if (err instanceof MyError) { handle it } else throw err }
Then I declare my routes with Koa router. Running on http is fine but running in jest with supertest causes thrown errors and 404s instead of the specific error codes it鈥檚 supposed to return
I know the correct error instances are being thrown even in the test context bc I put in debugger calls where my tests should throw errors and the code hits those error paths and throws. But the result in jest is that the expectations don鈥檛 match, and the test doesn鈥檛 end even though I awaited on supertest; the jest test ends but handles are left open and I have to kill the process to exit and jest warns me about open handles
I tried converting it to the old style supertest.end code but that didn鈥檛 change anything
Sorry would show you more specific code but on a plane lol. Can make a small example repo to reproduce but maybe that gives you an idea of what might be happening
Ahhhh I figured it out: The reason it was throwing was because in my test I was mocking out a middleware, but my mock implementation was bad - the Koa middleware needed to be an async function that awaits on next(), but instead I had a normal function that just called next(). The discrepancy between the server and the test was because the actual function, rather than the mocked one, did invoke next() properly.
Next, the reason I was getting open handles was because, when you use supertest with koa, you need to create a server using yourKoaApp.listen(), but that also means you need to clean it up and close the server.
I think it's safe to say this issue should be closed.
For anyone else having this issue, make sure that express-async-errors is in scope of where the tests are run. Simply adding require('express-async-errors') to the top of my test was enough to make this work.
Most helpful comment
For anyone else having this issue, make sure that
express-async-errorsis in scope of where the tests are run. Simply addingrequire('express-async-errors')to the top of my test was enough to make this work.