New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Async Reply functions (always emit errors) #1596
Async Reply functions (always emit errors) #1596
Conversation
105fda4
to
98ad7cb
Compare
This check is no longer reachable because `util.promisfy` will ignore subsequent calls to the callback method.
98ad7cb
to
9f815e8
Compare
Hey Matt, is your feeling still that this is a better way to go? If it is I will aim to dig in and leave some comments in the next day or so. |
This version gets my vote unless we deem the breaking changes undesirable. |
# Conflicts: # tests/test_reply_function_async.js
tests/test_reply_function_async.js
Outdated
.get('/') | ||
.reply(200, async (path, requestBody) => { | ||
t.equal(path, '/') | ||
t.equal(requestBody, '') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would make a better assertion if you passed something more specific in, probably both for the path and the body.
@@ -307,41 +306,29 @@ function RequestOverrider(req, options, interceptors, remove) { | |||
if (interceptor.replyFunction) { | |||
const parsedRequestBody = parseJSONRequestBody(req, requestBody) | |||
|
|||
if (interceptor.replyFunction.length === 3) { | |||
let fn = interceptor.replyFunction | |||
if (fn.length === 3) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could also consider checking if it is an AsyncFunction (and in that case not promisifying, regardless of the number of arguments):
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AsyncFunction
It ensures that an async reply function is awaited, even if the arguments have gotten messed up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have reservations on this. An async function and a function returning a promise should be treated the same in my book, but there is no way to sniff for the later.
With some quick testing, it looks like even if an async fn gets wrapped in promisify
it will resolve the whole chain as desired.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with the principle that an async function and a promise should be treated the same.
A conflicting principle (in this case) is that the number of arguments to a promise-returning function should not affect its behavior. I see why we did that here, and when we lived in the world of callbacks, why it would be necessary. Though going forward ideally we wouldn't care about the number of arguments to the function. My goal is to avoid surprises when someone makes a mistake.
I don't think we need to belabor this (and it's not so important in the scheme of things) – just wanted to convey where I was coming from.
@paulmelnikow based on other convos we've had in other PRs; would the preference be to change the calls of |
If we're going to change to a different test runner I think we may as well keep using |
Co-Authored-By: Paul Melnikow <github@paulmelnikow.com>
Co-Authored-By: Paul Melnikow <github@paulmelnikow.com>
🎉 This PR is included in version 11.0.0-beta.31 🎉 The release is available on: Your semantic-release bot 📦🚀 |
🎉 This PR is included in version 11.0.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Functions passed to `Interceptor.reply`, either to respond with an array of `[status, body, headers]` or with just the body, can now be async/promise-returning functions. BREAKING CHANGE: uncaught errors thrown inside of user provided reply functions, whether async or not, will no longer be caught, and will no longer generate a successful response with a status code of 500. Instead, the error will be emitted by the request just like any other unhandled error during the request processing.
Functions passed to `Interceptor.reply`, either to respond with an array of `[status, body, headers]` or with just the body, can now be async/promise-returning functions. BREAKING CHANGE: uncaught errors thrown inside of user provided reply functions, whether async or not, will no longer be caught, and will no longer generate a successful response with a status code of 500. Instead, the error will be emitted by the request just like any other unhandled error during the request processing.
Functions passed to `Interceptor.reply`, either to respond with an array of `[status, body, headers]` or with just the body, can now be async/promise-returning functions. BREAKING CHANGE: uncaught errors thrown inside of user provided reply functions, whether async or not, will no longer be caught, and will no longer generate a successful response with a status code of 500. Instead, the error will be emitted by the request just like any other unhandled error during the request processing.
This is a POC for #1557 and is offered as an Option B to #1572.
The difference between this change and #1572 is that this takes a hard line on how to handle errors in reply functions. It always emits an error (105fda4).
I personally believe this is the right design long term but it does introduce a breaking change.
Using the example from the docs:
Currently, if
readFile
errs, the request will succeed with a response that has a 500 status code.To achieve the same affect, the code would have to be rewritten by the consumer to:
However, I would argue that this is not the standard use case nor the most intuitive handling of a test.