Skip to content
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 middleware #148

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open

Conversation

UncleClapton
Copy link

closes #146

@changeset-bot
Copy link

changeset-bot bot commented Jul 5, 2021

⚠️ No Changeset found

Latest commit: 4e32dcf

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@codecov
Copy link

codecov bot commented Jul 5, 2021

Codecov Report

Merging #148 (4e32dcf) into master (2b81d76) will not change coverage.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff            @@
##            master      #148   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            1         1           
  Lines           80        78    -2     
=========================================
- Hits            80        78    -2     
Impacted Files Coverage Δ
src/index.js 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 2b81d76...4e32dcf. Read the comment docs.

@@ -39,20 +39,21 @@ describe("nc()", () => {
.expect("quick math");
});

it("supports async handlers", async () => {
it("supports async handlers and middleware", async () => {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add them as new test cases instead of editing existed ones?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it 👍

@UncleClapton
Copy link
Author

Hey! Just bumping this PR in case you missed it. Requested changes have been made!

Copy link
Owner

@hoangvvo hoangvvo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So sorry for the late review. I just have some questions.

};
const next = (err) => i < len
? err
? onError(err, req, res, next)
Copy link
Owner

@hoangvvo hoangvvo Jul 15, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would be its behavior when an error is thrown. In this case the execution inside the handler still goes on after await next()?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that's something I totally missed in my testing. my bad! Indeed errors aren't halting execution after await next().

It seems it's behaving this way because the error is handled inside of next() and never returned back. I found a solution that ensures that errors are propagated, but I can't find one that gives onError() an option to call next() and allow middleware to continue execution after doing so. Any ideas?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may need to decide on a behavior.

One thing we can do is to let next() throws and the error should propagate all the way up and only attach the error handler to the first handler:

handler1: await() -- onError()
     middleware1: await next() -- ⬆️
          middleware2: await next() - ⬆️
              middleware3: throw new Error()

But that is a breaking change since it will break if user have not been doing await next(), which is probably the case now.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My pending changes resolves error handling without having to unravel the stack. In the event that the error handler wishes to ignore the error and call next(), however, it leads to the following unexpected behaviour.

// ❌ = does not execute
// Middleware listed after .get() represents code to be executed after await next().

// Example: GET /
middleware1: await next()
    middleware2: await next()
        middleware3: throw new Error() -> onError() -> next()
            .get(handler): 
        middleware3: ❌ -- not expected to run, it gave up control after throwing
    middleware2: ❌ -- expected to run
middleare1: ❌ -- expected to run

This is where I'm running into problems with finding a decent solution. Do you think it's worth preserving this trait of error handling?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support async middleware chains
2 participants