jshttp / http-errors Goto Github PK
View Code? Open in Web Editor NEWCreate HTTP Errors
License: MIT License
Create HTTP Errors
License: MIT License
Would be useful if we could pass arbitrary properties to errors using constructors. e.g.:
new createError[code || name]([msg],[properties]))
this would match the createError function signature. For example, right now we can do:
createError(402, 'Your balance is too low.', {
detail: {
currentBalance: 100,
price: 150,
},
})
but not
new createError.PaymentRequired('Your balance is too low.', {
detail: {
currentBalance: 100,
price: 150,
},
})
instead of :
if (!foundUser) return next(createError.NotFound("User not found"));
i want to send an object like this :
if (!foundUser) return next(createError.NotFound(
{
field : "email",
message: "User not found"
}
));
// the same as : res.status(404).json({field:"email", message:"User not found"})
as referenced in jshttp/jshttp.github.io#35
I think ignoring .expose
in the options object is somewhat counter intuitive. What's your position on this?
We could do something like
err = err || new Error(msg || statuses[status]);
err.expose = status < 500;
for (var key in props) err[key] = props[key];
err.status = err.statusCode = status;
Hi,
is it possible to add an "errors" support to properties.
For example something like this:
const errors = { name: ["required"] }
new BadRequest('validation error', { errors })
Because now I must extend a BadRequest error like that:
createError.ValidationError = class ValidationError extends createError.BadRequest {
constructor(message, errors) {
super(message)
this.errors = errors
}
}
and IMHO it should be out of the box supported.
What do you think?
Create a new error object with the given message msg
.
The error object inherits from createError.HttpError
.
var err1 = new createError.NotFound()
var err2 = new createError.NotImplemented('Route not implemented', { expose: true })
code
- the status code as a numbername
- the name of the error as a "bumpy case", i.e. NotFound
or InternalServerError
.msg
- (optional) the message of the errorproperties
- (optional) custom properties to attach to the objectHi, I would like to start using the new isHttpError
function added in e11f87d. Would you be able to do a release to npm?
Is there any point in doing create(404, 'message')
when you can use create[404]('message')
?
Also, you can do create(404, 'message')
as well as create('message', 404)
, which will be pain to support if we decide to change that.
I'm now thinking about literally shadowing global Error object with this one:
var Error = require('http-error')
throw new Error('this would work as usual')
throw new Error[404]('this would work as http error')
... and things like treating numbers as status codes might break the idea.
Hi all,
Please consider add support for expose
property in new createError.[code || name]([msg]))
like syntax.
We use new createError.name([msg]))
a lot because of its readability. It also mitigates the need to remember all those status codes. Being able to do something like below will be of great help.
var err = new createError.NotFound("Show this error to client.", {expose: true, ...});
I'm trying to use this library in react-native. RN uses the V8 JS engine during development, but JSC for releases.
V8 supports Error.captureStackTrace()
, but JSC doesn't.
Hence, unguarded use of Error.captureStackTrace()
in the library causes a TypeError
exception for release builds:
TypeError: Error.captureStackTrace is not a function. (In 'Error.captureStackTrace(o)', 'Error.captureStackTrace' is undefined)
Would it be possible to guard calls to captureStackTrace()
in the library?
Here's an example: auth0/react-native-auth0#33
You would expect these usages to log identically:
import createError from 'http-errors'
console.log(
JSON.stringify(createError('Message 1.')),
JSON.stringify(createError(new Error('Message 2.')))
)
They actually output this:
{"message":"Message 1."} {"expose":false,"statusCode":500,"status":500}
For context, I am attempting to do snapshot testing of errors that have been created various ways and am having many surprises.
util.inherits() is discouraged in favor of ES6 class and extends syntax:
https://nodejs.org/docs/latest/api/util.html#utilinheritsconstructor-superconstructor
Based on #103
Users likely expect to be able to pass custom properties to errors when creating them via the shortcut methods such as createError.NotFound()
.
Proposed change would look something like:
const createError = require('http-errors')
createError.NotFound({message: "Aw shucks", data: { foo: "bar" } }) // does not work today
You need to use the createError({...})
form to pass custom properties to an error.
createError(404, {message: "Aw shucks", data: { foo: "bar" } })
There's a few caveats with the current implementation, namely you can't set status
via properties.
createError({ status: 404, message: "Aw shucks", data: { foo: "bar" } })
// status is ignored, will create a 500 server error with provided message and data fields
There is also a very high arity for createError
, which should be locked down into a stable interface.
(code)
for (var i = 0; i < arguments.length; i++) {
var arg = arguments[i]
var type = typeof arg
if (type === 'object' && arg instanceof Error) {
err = arg
status = err.status || err.statusCode || status
} else if (type === 'number' && i === 0) {
status = arg
} else if (type === 'string') {
msg = arg
} else if (type === 'object') {
props = arg
} else {
throw new TypeError('argument #' + (i + 1) + ' unsupported type ' + type)
}
}
Any of these changes would be semver major. There aren't plans for a major release of http-errors
yet, but these are things Im thinking about.
These are both topics related to the interfaces exposed by the library for accepting arguments, which can use some rethinking.
In my app I use res.status(err.status).send(err)
to send error. send
uses JSON.stringify
for objects. Stringified error does not contain message
.
Example:
var createError = require('http-errors');
var error = createError(404, 'message', { description: 'description' });
var error2 = createError(404, { message: 'message', description: 'description' });
console.log(JSON.stringify(error)); // {"description":"description"}
console.log(JSON.stringify(error2)); // {"description":"description"}
I noticed the docs don't mention using the named error constructors directly (i.e. new NotFound()). Is there a reason why? also since they are factories it seems that throw NotFound would be the call but ESLint balks at the capitalization. Is the future going to using these as legit constructors or heading towards a camelCase factory var?
The docs do not mention using the named constructor directly though the code exports them.
Judging by tests, the expectation is that when an error.status
is < 500, then expose
will be true, however, the code has
ClientError.prototype.expose = false;
the test case will failed in koa
:
describe('when props include status', function(){
it('should be ignored', function(done){
var ctx = context();
try {
ctx.throw(400, 'msg', {
prop: true,
status: -1
});
} catch (err) {
assert('msg' == err.message);
assert(400 == err.status);
assert(true === err.expose);
assert(true === err.prop);
done();
}
})
})
Is it intentional?
not sure how we can standardize this... last thing i want is for other people to use a different property name. also want all the text casing to be the same so people don't do:
err.headers = {
'content-type': 'text',
'Content-Type': 'application/json',
}
maybe set .headers = {}
by default?
I was looking at how my projects are pulling in packages like inherits
and setprototypeof
and http-errors came up a lot.
I see that there's some discussion of breaking changes in issues like #104 and requests for better class interop in #98. Would there be appetite for also removing inherits
and setprototypeof
along with those for a new major version?
I want to set error response headers when an error occurred. Like Content-Type = application/json. When I passed the {'content-type': 'application/json; charset=utf-8'} as err.headers nothing changed.
let err = new Error("{message: 'error'}");
err.status = 405;
err.headers = {"content-type": 'application/json; charset=utf-8'};
err.expose = true;
throw err;
Thanks in advance.
To allow better interoperability with ES6 classes (which are forced to call the super() constructor) it is better to add the following condition to the HttpError constructor:
if (this.constructor === HttpError) {
throw new TypeError('cannot construct abstract class')
}
This way the class can be extended with a concrete class like this:
class MyHttpError extends HttpError {
constructor() {
super();
...
}
}
A variant using ES6 classes as base class is shown here but the same works with old school constructor functions as well.
Node 16.9 / V8 9.3 added a cause
property to Error
.
Can this support be added into this package? Even if it's not running a version that supports the extra Error
constructor options, it would be good to attach it to HttpError.cause
anyway.
some times we need to create an error, based on origin internal error.
so, I'd like to create error like this
catch (err) {
if (err instanceof mongoose.Error.CastError) {
throw new createError.BadRequest(err);
} else ...;
I would expect
httpError(500, httpError(402)).statusCode
to be 500, but it's 402.
(The use case here is that I have a try
/catch
statement that turns all exceptions into HTTP 500s by default, and it's not working correctly when the original exception is already an httpError
.)
Displaying the error message in the response body for errors >= 500 requires {expose: true}
in properties
. It would be nice is this was documented in the README.
validateId = (req, res, next) => {
if (!mongoose.Types.ObjectId.isValid(req.params.id)) {
return next(createError(404));
}
next();
};
Getting
{
"message": "Not Found",
"name": "NotFoundError"
}
but with status code 500.
Seems like the current master
branch have some broken tests when running Node@8 and Node@9. I realized that with the PR: #107.
Similar error in both cases: https://github.com/jshttp/http-errors/actions/runs/8278069455/job/22650768076#step:10:104, here is an screenshot in case that you can't access to the logs:
Currently throwing errors with non-error status codes works, but causes a deprecation notice to log:
There are instances where it is perfectly valid to throw an error yet respond with a 200 status. GraphQL servers are required to respond with a 200 status when errors were encountered within resolvers (see graphql/express-graphql#118 (comment)).
You can see this use case in action here: https://github.com/jaydenseric/graphql-api-koa/blob/v0.2.0/src/index.mjs#L182.
Hi! I read issue #69 where it has been shared that it should be possible to do the following:
const errors = { name: ["required"] }
createError(400, 'validation error', { errors })
Am I correct to assume that this should give the following back?:
{
error: "Bad Request",
message: "validation error",
errors: { name: ["required"] },
statusCode: 400
}
Because if that should be the case, I am currently only getting
{
error: "Bad Request",
message: "validation error",
statusCode: 400
}
I am wondering if I am misunderstanding this functionality or implementing it wrong.
I'm not sure if this is specific to http-errors or to TypeScript, but this is the issue I'm having: it seems that instanceof
doesn't work when I'm receiving a HttpError
from another package.
To reproduce:
npm init
npm install typescript http-errors --save
npm install @types/http-errors --save-dev
index.ts
:import * as httpErrors from "http-errors";
export function getError() {
return new httpErrors.Unauthorized("Whatever");
}
To have exactly the same as I did, run ./node_modules/typescript/bin/tsc --init
and change target
from es5
to es6
.
Now run npm link
in the directory and create a new project somewhere else and npm link <first-package-name>
to add a symlink in the node_modules
directory.
In the new project, add some code like this:
import * as httpErrors from "http-errors";
import { getError } from "<first-package-name>";
const err1 = new httpErrors.Unauthorized("Foo");
console.log(err1 instanceof httpErrors.HttpError); // will output true
const err2 = getError();
console.log(err2 instanceof httpErrors.HttpError); // will output false!
Again, I'm not sure if this is TypeScript in general, or the way the code in http-errors is contructed. I'm no JS/TS expert, so I'm interested in your opinion/advice.
For your convenience, I've created a repo that you can just pull and then run node index.js
.
I am sorry if I had written rude things because I am poor at English.
When I specified Error
as the second argument, there was a key like status
or statusCode
, so the status code of the first argument was overwritten.
Error is like this.
{ MessageRejected: Email address is not verified.....
message: 'Rejected',
code: 'ClientError',
statusCode: 400}
And, I written the following code.
try {
....
} catch (e) {
throw createError(500, e, { errors: [{ msg: 'sending mail was failed' }] })
}
In the case of the above error, the first argument is ignored and the return value of status is forced to 400.
And I return the status of the Error to the client, as the status code of the response.
This is caused by the following code.
for (var i = 0; i < arguments.length; i++) {
var arg = arguments[i]
if (arg instanceof Error) {
err = arg
status = err.status || err.statusCode || status
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
I think it's strange that status
was changed by the first argument , but it will changed again.
It's not unsual for APIs, especially private ones, to use non-standard response codes in the 400 range for specific errors. As is, the module does not allow this - it will convert any non-standard code to a 500. As an example here's what I'm doing in my app:
var err = http_errors(471, 'Invalid API Key.')
err.status = 471;
Ideally, in my opinion, there would be a way to pass an array of additional codes when requiring the library, which would allow us to easily have a JSON file containing our extended error codes while allowing the library to validate the code against the list of available/valid codes.
Holy crap. Just requiring this module add an entire 5 seconds of start up time on my machine!!! I have not yet dug into it.
Okay, I know how this sounds. Everybody knows eval
is evil, but hear me out.
Currently errors created by this module have their constructor.name
set to either Error
or one of ServerError
and ClientError
(see my other ticket on consolidating the different factories).
It would be nice if they instead had the name that is used to export them, e.g. ImATeapot
.
There is no way to set the name of a function after the fact, so this would require creating the constructors dynamically -- kinda like this.
The benefit would be that it would be easier to distinguish the various error functions exported by this module, especially in the console (where they currently just appear as [Function: ClientError]
etc, rather than [Function: NotFound]
and such).
The createError([status], [error], [properties])
api allows the user to specify properties
,
e.g.: throw createError(404, "test", { expose: false })
.
However, the constructor api new createError[code || name]([msg]))
does not.
Is there a reason for this? I would like to be able to e.g.:
throw new createError.NotFound("test", { expose: false })
In my use case I would like to use the expose
flag to determine if the error message should be exposed to the end-client. In some cases (e.g., auth) the 4xx client errors messages are sensitive so I'd like to return an ambiguous message in the case that the http error doesn't have the expose flag set.
Is it possible to check for the existence of Error.captureStackTrace()
before using it?
I was trying to use http-errors
on the browser side via Browserify, and it blew up with:
TypeError: Error.captureStackTrace is not a function
(on Firefox).
Any way to check for its existence before using, since it's non-standard to some environments?
Currently the "constructors" are actually just factory functions and we have a total of three such factories in the code that do pretty much the same thing (ClientError
, ServerError
and the exported function).
The only reason ServerError
and ClientError
have any inheritance at all is that the __proto__
property of the new error is manipulated directly. This is incompatible with some possible environments (the double underscores are there for a reason).
It would be nice if the two constructors were actual constructors (i.e. return this
, not a retrofitted error). For an example of how this would work see [email protected].
The obvious drawback is that Object.prototype.toString
returns [object Object]
instead of [object Error]
and util.isError
returns false
(though instanceof checks pass as one would expect). The benefit is that this approach can be made to work in environments that don't support overriding __proto__
.
I was surprised I couldn't subclass errors. I would have expected my ValidationError class would support an instanceof
check against itself.
const { BadRequest } = require('http-errors')
const assert = require('assert')
class ValidationError extends BadRequest {}
const err = new ValidationError()
console.log(err.name)
// "BadRequestError"
// err should be an instance of ValidationError
assert(err instanceof ValidationError)
Question: would it be possible to include the typescript typings, which are currently available via @types/http-errors, directly into the package?
And by that, also provide for commonjs default export support?
I'm trying to figure out how to identify the errors created with this library.
According to the README, "All errors inherit from JavaScript Error and the exported createError.HttpError." so my intention is to do something like
createError('...') instanceof createError.HttpError; // true
which works great unless an actual error is passed as an argument:
createError(new Error('...')) instanceof createError.HttpError; // false
In this case, createError()
returns the original error instead (after adding some properties).
Because JS doesn't support multiple inheritance, I guess the remaining option is to rely on duck typing. For example:
const isHttpError = value => value instanceof Error && 'status' in value && 'expose' in value;
isHttpError(createError(new Error('...'))); // true
I wonder if this is the recommended approach and, if so, I'd suggest to update the documentation accordingly.
When I use next (createError (500)) to create an httpError, and the error is returned to the client, will the remaining code on the server be stopped? Or will it return to the next place and continue to execute downward?
After updating NPM packages, this exception started happening on each request.
TypeError: Cannot read properties of undefined (reading 'split')
at toIdentifier (D:\home\site\wwwroot\node_modules\send\node_modules\toidentifier\index.js:24:6)
at forEachCode (D:\home\site\wwwroot\node_modules\send\node_modules\http-errors\index.js:245:16)
at Array.forEach (<anonymous>)
at populateConstructorExports (D:\home\site\wwwroot\node_modules\send\node_modules\http-errors\index.js:243:9)
at Object.<anonymous> (D:\home\site\wwwroot\node_modules\send\node_modules\http-errors\index.js:30:1)
at Module._compile (node:internal/modules/cjs/loader:1101:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Module.require (node:internal/modules/cjs/loader:1005:19)
I did an npm i http-errors@latest
http-errors
get installed, life goes on
The following error turned up
npm ERR! code E404
npm ERR! 404 Not Found: flatmap-stream@https://registry.npmjs.org/flatmap-stream/-/flatmap-stream-0.1.1.tgz
Some dependency of the package has flatmap-stream as a dependency. Please update the dependencies
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.