-
-
Notifications
You must be signed in to change notification settings - Fork 20
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
add isFastifyError #86
Conversation
Should i change Line 39 in d61f38e
to FastifyError.prototype[Symbol.toStringTag] = 'FastifyError' ? |
I guess that is what you want. Probably should be then a semver major. |
@@ -36,7 +36,7 @@ function createError (code, message, statusCode = 500, Base = Error) { | |||
|
|||
this.statusCode = statusCode || undefined | |||
} | |||
FastifyError.prototype[Symbol.toStringTag] = 'Error' | |||
FastifyError.prototype[Symbol.toStringTag] = 'FastifyError' |
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.
Potentially breaking change and should result in a major versoin bump
@@ -47,4 +47,11 @@ function createError (code, message, statusCode = 500, Base = Error) { | |||
return FastifyError | |||
} | |||
|
|||
function isFastifyError (value) { | |||
return Object.prototype.toString.call(value) === '[object FastifyError]' |
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'm hardly -1 on this approach.
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.
@mcollina I believe you want to say: "I'm strongly -1". Saying "I'm hardly" means "I'm in favor of this".
What is your disagreement with this? An instanceof
check would break if someone is using their own import of fastify-error
to check an error generated by Fastify's internal import of fastify-error
.
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.
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.
Would it work with a custom symbol?
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.
No, the toStringTag
is a spec defined symbol.
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.
We can just set our custom
Symbol for every instance created by the constructor and check for it. We already do this in our codebase.
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.
True. But we are delving deeper into hack territory.
What about the classic? function isFastifyError (value) {
return (
typeof value === 'object' &&
value !== null &&
value.name === 'FastifyError'
)
} I mean... if somebody changes the name of the error it is basically saying it is not a FastifyError anymore. Like we change the name from Error to FastifyError to indicate we have our own Error Class. |
Going back to the original issue: what problem are we trying to solve for here? What usage do we want? I do not see a good case to use that method that's not a code smell. At this point The fact that the whole Fastify ecosystem could be built without this existing should tell something. |
🤷♂️ I only have the recommendation to prevent "not an instance of" errors. |
My best recommendation would be to have a utility to check if it has a |
The question is if we should instead improve the documentation what we consider best practise and about ducktyping FastifyError. I could do that instead, if we agree on |
@@ -47,4 +47,11 @@ function createError (code, message, statusCode = 500, Base = Error) { | |||
return FastifyError | |||
} | |||
|
|||
function isFastifyError (value) { | |||
return Object.prototype.toString.call(value) === '[object FastifyError]' |
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.
Would it work with a custom symbol?
t.plan(8) | ||
|
||
const NewError = createError('CODE', 'Not available') | ||
t.equal(isFastifyError(NewError()), true) |
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 wonder if we should consider the createError
instances as "application error" instead of Fastify Error
This is easy as adding a custom unique symbol to every instance created by the constructor and then checking for it inside the isFasitfyError function. |
I guess you could do const kFastifyError = Symbol.for('FastifyError') And add it like we do with toStringTag. |
I typically use this module for my applications too. The only way to know if an error comes from Fastify is to check the prefix of the |
So your objection is the object name? |
My objection is on how this is supposed to be used. I would instanceof individual errors, but not a blanket check against all the errors this module can produce. If somebody wants all Fastify core errors, they can do |
This is not reliable. See the attached example. Within it is an 'use strict'
const VError = require('verror')
const foo = require('foo')
try {
foo()
} catch (error) {
console.log(error instanceof VError)
}
const error = VError('not foo')
console.log(error instanceof VError) This example will output the following: $ node 00_main/index.js
false
true Notice that both the "main" application and the dependency rely on the exact same version of If |
I agree with this. This proposal is also about knowing if the error is a fastifyError, regardless if Fastify, a plugin, or user code threw it. You are right, though, when you say that it is achievable checking for code and statusCode. I was thinking about providing a utility that can lower the barrier for the developers. I saw that error handling is usually one of the worst parts of the applications, and one of the barriers is handling application errors vs. unexpected errors. Boom has isBoom to allow the users check the error inside errorHandlers and act accordingly. Hope this makes sense. |
Also dont forget jest. It messes also instanceof Error up. Maybe we should find a solution based on Symbol.hasInstance? https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/hasInstance |
Here is my taken on how I would implement this for Fastify: if (err.code.indexOf('FST_') === 0) {
// All Fastify errors go there.
} |
How would that solve the generic usage case of this module? I think the module name is confusing the goal. As I understand the desire, it is to determine if an error instance has been created by this module. Not necessarily that an error instance is one from the Fastify framework. |
|
@mcollina,, checking if an error is a fastify error could allow the users to know if the error is an application logic error (fastifyError) or any other unhandled error. This information will enable the users to act accordingly: send a report to external tools, set proper code for the response, etc. Basically, the ordinary operations that we all usually do inside error handlers. |
@fox1t |
@fox1t the solution described in #86 (comment) is perfect for that use case as it uses error codes. |
Pardon me? I was making the same point @jsumners made since I had the same impression that not everyone was on the same page. I don't have to convince anyone. Since I proposed this in the first place I tried to make sure that everyone understands what I am proposing. |
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 think is a good case in https://github.com/hapijs/boom/blob/master/lib/index.js#L92-L108. Both using Symbol.hasInstance
and special parameters to judge an instance
@@ -37,6 +39,26 @@ const CustomError = createError('ERROR_CODE', 'Hello %s') | |||
console.log(new CustomError('world')) // error.message => 'Hello world' | |||
``` | |||
|
|||
#### isFastifyError | |||
|
|||
The module exports a isFastifyError-function that you can use to check if a value is of type FastifyError, it takes one parameters: |
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.
The module exports a isFastifyError-function that you can use to check if a value is of type FastifyError, it takes one parameters: | |
The module exports a isFastifyError-function that you can use to check if a value is of type FastifyError, it takes one parameter: |
Closing due to inactivity (lol) |
Closes #17
Checklist
npm run test
andnpm run benchmark
and the Code of conduct