Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lib/response.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,11 @@ module.exports = res
res.status = function status(code) {
// Check if the status code is not an integer
if (!Number.isInteger(code)) {
throw new TypeError(`Invalid status code: ${JSON.stringify(code)}. Status code must be an integer.`);

Choose a reason for hiding this comment

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

What if the code is an object? String(code) will give [Object object]

Choose a reason for hiding this comment

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

Likely, they wanted to show what the user has passed.

Copy link
Author

Choose a reason for hiding this comment

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

Likely, they wanted to show what the user has passed.

You raise a valid point about object serialization. However, I believe the current approach with String(code) is the right solution for the following reasons:

Crash Prevention: The primary goal is to prevent server crashes. JSON.stringify() causes an uncaught TypeError with BigInt, which crashes the entire server. This is a critical issue that needs to be fixed.

Type Information: The error message format ${String(code)} (${typeof code}) actually provides more useful debugging information than JSON.stringify() in many cases:
For BigInt: "200 (bigint)" vs crash
For objects: "[object Object] (object)" vs "{"a":1}"
For functions: "function(){} (function)" vs "{}"
For arrays: "1,2,3 (object)" vs "[1,2,3]"

Practical Usage: Status codes are typically integers, strings, or occasionally undefined/null. Objects and functions as status codes are extremely rare edge cases that indicate programming errors rather than legitimate use cases.

Consistency: Using String() provides consistent behavior across all JavaScript types without special handling.

If we wanted to show more object details, we could use a try-catch approach:
But this adds complexity for a rare edge case. The current solution prioritizes crash prevention and provides sufficient debugging information for the vast majority of real-world scenarios.

What do you think? Should we stick with the simple String(code) approach, or would you prefer the try-catch solution for better object serialization?

throw new TypeError(`Invalid status code: ${String(code)} (${typeof code}). Status code must be an integer.`);
Copy link
Contributor

Choose a reason for hiding this comment

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

As @abhisekp pointed out in #6848 (comment), this will print objects as [Object object], but it has other drawbacks. While you (or your LLM) claim that this will prevent crashes, this change will introduce new problems if someone passes an object with null prototype (Object.create(null)) - see #6756 (comment).

}
// Check if the status code is outside of Node's valid range
if (code < 100 || code > 999) {
throw new RangeError(`Invalid status code: ${JSON.stringify(code)}. Status code must be greater than 99 and less than 1000.`);
throw new RangeError(`Invalid status code: ${String(code)} (${typeof code}). Status code must be greater than 99 and less than 1000.`);
}

this.statusCode = code;
Expand Down
36 changes: 36 additions & 0 deletions test/res.sendStatus.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,41 @@ describe('res', function () {
.get('/')
.expect(500, /TypeError: Invalid status code/, done)
})

it('should raise error for BigInt status code', function (done) {
var app = express()

app.use(function (req, res) {
res.sendStatus(200n)
})

request(app)
.get('/')
.expect(500, /TypeError: Invalid status code: 200 \(bigint\)/, done)
})

it('should raise error for string status code', function (done) {
var app = express()

app.use(function (req, res) {
res.sendStatus('200')
})

request(app)
.get('/')
.expect(500, /TypeError: Invalid status code: 200 \(string\)/, done)
})

it('should raise error for object status code', function (done) {
var app = express()

app.use(function (req, res) {
res.sendStatus({ status: 200 })
})

request(app)
.get('/')
.expect(500, /TypeError: Invalid status code.*\(object\)/, done)
})
})
})
12 changes: 12 additions & 0 deletions test/res.status.js
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,18 @@ describe('res', function () {
.get('/')
.expect(500, /Invalid status code/, done);
});

it('should raise error for BigInt status code', function (done) {
var app = express();

app.use(function (req, res) {
res.status(200n).end();
});

request(app)
.get('/')
.expect(500, /TypeError: Invalid status code: 200 \(bigint\)/, done);
});
});
});
});
Expand Down