Skip to content

Uncaught exception causes Express to set to undefined basic request parameters #5842

Description

@NicoAdrian

Consider this code:

const express = require('express')
const app = express()
const port = 3000

app.get('/foo/:bar', (req, res) => {
  res.on('finish', () => console.log('onFinish: ' + req.params.bar));
  // uncaught exception
  'nothing' in undefined;
})

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`)
})

curl http://localhost:3000/foo/blablabla will cause Express to:

  1. Send HTTP 500 (expected)
  2. Crash (not expected)

==> TypeError: Cannot read properties of undefined (reading 'bar')

After the uncaught exception, req.params is undefined (among other req parameters, not listed here). Thus, trying to access bar from undefined is also an exception, causing the server to crash and terminate.

Looks like Express "clears" some variables in the req object.

Activity

  1. danizavtz commented on Aug 21, 2024

    @danizavtz

    Looks like a problem with the event you are handling the event finish. if we check the documentation this event:

    Emitted when the response has been sent. More specifically, this event is emitted when the last segment of the response headers and body have been handed off to the operating system for transmission over the network.

    so I'm guessing that in this logical scope it is no longer possible to access the object property you want. And that is why you receive an undefined.

    If you change finish to end everything work as you expected.

  2. IamLizu commented on Aug 21, 2024

    @IamLizu
    Member

    Hi @NicoAdrian 👋

    I think the uncaught exception in Node causes a crash unless properly handled. And trying to access the req.params after that uncaught exception will be unpredictable because the request life cycle is not the same.

    I would add a global error handler,

    app.use((err, req, res, next) => {
        console.log("error handler: " + err.message);
        res.status(500).send("Something broke!");
    });
  3. NicoAdrian commented on Aug 21, 2024

    @NicoAdrian
    Author

    Looks like a problem with the event you are handling the event finish. if we check the documentation this event:

    Emitted when the response has been sent. More specifically, this event is emitted when the last segment of the response headers and body have been handed off to the operating system for transmission over the network.

    so I'm guessing that in this logical scope it is no longer possible to access the object property you want. And that is why you receive an undefined.

    If you change finish to end everything work as you expected.

    The req express (or is it ?) object is still accessible, with many properties. But the property params (also the baseUrl property for instance).

    The end and finish events serve different purposes:

    • end is related to the end of reading data from the incoming request
    • finish (what I want) is related to the completion of writing data to the outgoing response (writable stream)

    Scope shouldn't be an issue: I still have the req.params in scope. I go back to my first question: Why is it cleared by express ? (or NodeJS ?)

  4. IamLizu commented on Aug 21, 2024

    @IamLizu
    Member

    Hi, It is not cleared by Express or Nodejs, rather depends on the request life-cycle. Please allow me to clear it out a few hours later, I am currently not in front of my computer.

    PS: Please allow me to convert this to a discussion, if the need arises, we will revert this back to issue.

  5. converted this issue into a discussion #5843 on Aug 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions