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

HTTP Server: incorrect error message if status code is set to a string (like ENOENT) #9027

Closed
nfriedly opened this issue Oct 11, 2016 · 3 comments
Labels
http Issues or PRs related to the http subsystem.

Comments

@nfriedly
Copy link
Contributor

nfriedly commented Oct 11, 2016

  • Version: 6.5.0
  • Platform: Darwin Nathans-MBP.lan 16.0.0 Darwin Kernel Version 16.0.0: Mon Aug 29 17:56:20 PDT 2016; root:xnu-3789.1.32~3/RELEASE_X86_64 x86_64
  • Subsystem: http

https://github.com/nodejs/node/blob/master/lib/_http_server.js#L190 converts the http status code to a number and then validates that it's within an appropriate range, throwing an error if it is not. However the error message includes the converted value rather than the original value.

If you have app code that does something dumb like copying err.code to the http status code, and err.code happens to be, for example, "ENOENT", the error message that is thrown is:

RangeError: Invalid status code: 0
     at ServerResponse.writeHead (_http_server.js:192:11)
     at ServerResponse.writeHead (/home/vcap/app/node_modules/on-headers/index.js:55:19)
     at ServerResponse._implicitHeader (_http_server.js:157:8)
     at ServerResponse.OutgoingMessage.end (_http_outgoing.js:559:10)
     at ServerResponse.send (/home/vcap/app/node_modules/express/lib/response.js:205:10)
     at ServerResponse.json (/home/vcap/app/node_modules/express/lib/response.js:250:15)
     at app.use (/home/vcap/app/config/error-handler.js:38:28)
     at Layer.handle_error (/home/vcap/app/node_modules/express/lib/router/layer.js:71:5)
     at trim_prefix (/home/vcap/app/node_modules/express/lib/router/index.js:310:13)

A better error message in this situation would be

RangeError: Invalid status code: ENOENT

I'll have a PR with a patch and a test for this shortly.

@fundon
Copy link
Contributor

fundon commented Oct 11, 2016

I found most libraries will to custom HTTP Error to cover that.

Like below:

function CustomError (code, message) {
   this.code = code
   this.status = this.statusCode = code in http.STATUS_CODES ? code : 500 // if you want
   this.message = message || http.STATUS_CODES[this.status]
   this.name = this.constructor.name
   Error.captureStackTrace(this, this.constructor)
}

Is there better practice?

@mscdex mscdex added the http Issues or PRs related to the http subsystem. label Oct 11, 2016
@nfriedly
Copy link
Contributor Author

@fundon That looks good to me, but it's kind of orthogonal to this issue. Node.js still should give helpful error messages when the user (or library) gets something wrong.

nfriedly added a commit to nfriedly/node that referenced this issue Jan 17, 2017
HTTP ServerResponse.writeHead previously coerced the given statusCode
to an integer to validate it, then threw an error with the converted number
if it was invalid. This meant that non-numeric input led to confusing
error messages.

This change makes the input validation more strict, throwing on any non-integer
input rather than silently coercing it.

Of note:

* Strings (e.g. '200') were previously accepted, now they cause a TypeError

* Numbers with decimals (e.g. 200.6) were previously floored, now they cause
  a RangeError (with the original value included in the error message).

Fixes nodejs#9027
@nfriedly
Copy link
Contributor Author

nfriedly commented Mar 1, 2017

Fixed in a4bb9fd

@nfriedly nfriedly closed this as completed Mar 1, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
http Issues or PRs related to the http subsystem.
Projects
None yet
Development

No branches or pull requests

3 participants