-
-
Notifications
You must be signed in to change notification settings - Fork 16.7k
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
Define error-handling middleware functions explicitly (without arity detection) #2896
Comments
This, this this! I have thought this for a very long time. The implicit behavior of the error handlers is confusing to beginners and advanced users alike. I would support making this to 5.0 and explicitly deprecating the old way, for future removal. And possibly even adding as a new feature in 4.0 as a point release. Thanks @feross for bringing this up. |
I think this is probably a Good Idea™. Maybe we should do some assessment of how much |
My guess is that since it is the only way to handle errors it is used in EVERY express app :) Right? I know for sure that I use it in all of my apps. |
It would have to be changed in the |
Do you have a link to the code that you are saying would need to change? |
https://github.com/expressjs/errorhandler/blob/master/index.js#L83 This is just an example. There is going to be other third-party modules that are going to have to be changed as well, and I'm not sure if it's possible to handle carefully. |
This looks like a nice idea. The implicit error handler behaviour is one of the more surprising parts of the api imo. |
The interface looks lovely. I am assuming the extended example looks something like this:
|
Major 👍 to this - my linter complains about the unused parameter all the time even though I can't remove it. |
@billinghamj I use |
This API is really nice 👍 |
Nice option,
Another one option. Using chaining to handle error. This will give power to handle error at all levels.
|
This is a neat idea, but it would have to be a feature because this is a gigantic breaking change. There are a lot of Express dependents out there and this breaks all of them, no exceptions. Personally, I don't think deprecation is even appropriate. |
There's no reason not to continue supporting the old method, but just outputting a warning to the console explaining what the new way is. The old way can then be removed in the next major version, or perhaps the one after. |
There absolutely is. How does |
Imo, it would be best not to change the behavior of error handlers at the same time as moving away from the arity detection. If they are independent changes, and the removal of the arity detection makes no difference to the functional behavior, there isn't much to worry about from what I can see. Why would |
@billinghamj, error handlers can be used in more than just |
Regardless to various things to work out, what I hear loud and clear: Express should not use argument arity to differentiate between error and non-error handlers, and I 100% agree. |
+1 for this. I've stumbled on this so many times, because Current workaround to stop jshint from complaining in middleware that doesn't use next is (without turning off the jshint flag that is): function(error, req, res, next) {
next = next || null;
//do stuff
} But that's just... meh |
Its been said a lot already but to add I faced this multiple times also with eslint, reverted to using: |
If anyone is interested, I opened a PR in the |
This issue can be solved if a new approach is devised that allows express to differentiate between error and non-error handlers. For example a property User-facing APIUsers creates an error handler by calling const errorHandler = (err, req, res, next) => {...}
app.use(foo, [bar, express.createErrorHandler(errorHandler)]) ImplementationApproach 1: Assign and check express.isErrorHandler = (fn) => {
return Boolean(fn.isExpressErrorHandler);
}
// assign the property `isExpressErrorHandler = true`
express.createErrorHandler = (fn) => {
const clonedFn = fn.bind({})
clonedFn.isExpressErrorHandler = true;
return clonedFn;
} Approach 2: Assign and check a wrapper object express.createErrorHandler = (fn) => {
return {
isExpressErrorHandler: true,
handler: fn,
}
}
express.isErrorHandler = (handler) => {
return Boolean(handler.isExpressErrorHandler);
} |
@golopot, can you check out the open PR for this? pillarjs/router#59 Your thoughts would be appreciated there, thanks! |
I propose adding an explicit
app.error
method for defining error-handling middleware functions:Instead of:
It's so easy to forget the
next
argument when it's not being used in the body of the function, and that changes the whole meaning of the middleware.express
is one of the only packages that has this pattern. Others that used this pattern in the past (i.e.superagent
) have since removed it.Furthermore, this clashes with popular linting rules like ESLint's
no-unused-vars
rule which enforce that all named arguments must be used in the function body. Users who see this rule and remove the un-unsednext
parameter will be unwittingly changing the behavior of their program.No one expects removing an unused parameter to change the behavior of a program.
The four argument middleware convention should be deprecated in favor of
app.error
, but support for it could remain for a long time, or even indefinitely. I just want to be able to recommend that folks useapp.error
going forward.The text was updated successfully, but these errors were encountered: