Skip to content

fix: prevent stale error handler references in file node append mode#5460

Open
Dennis-SEG wants to merge 2 commits intonode-red:masterfrom
Dennis-SEG:fix/file-node-error-handler
Open

fix: prevent stale error handler references in file node append mode#5460
Dennis-SEG wants to merge 2 commits intonode-red:masterfrom
Dennis-SEG:fix/file-node-error-handler

Conversation

@Dennis-SEG
Copy link
Contributor

Summary

Fixes #5453 - File node's append mode could have stale error handler references when stream is reused.

Changes

Added per-write error handling with a writeDone flag to ensure correct message context is used and prevent double done() calls.

Test Plan

  • All file node tests pass
  • Manual testing with write errors in append mode

Copy link
Member

@knolleary knolleary left a comment

Choose a reason for hiding this comment

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

The original issue says the error handler is setup once and references the original done and msg objects.

With this PR, that error handler is still in place in line 186; it is still registering the handler just as it did before.

For the proposed changes, the docs for stream.write (ref) say the callback is called before the error event is emitted. I can't see how the logic around writeDone will work.

It's also worth noting that the callback will be passed any error as the first argument (again, before the error event is emitted). This could be used to call the right scoped nodeSend/done.

Use write callback's error argument instead of adding/removing error handlers.
This ensures the correct msg/done scope is used for each write operation.

The stream-level error handler now only handles errors for dynamic filenames,
while static filename writes handle errors via the write callback.

Addresses review feedback from @knolleary.

Fixes node-red#5453
@Dennis-SEG Dennis-SEG force-pushed the fix/file-node-error-handler branch from 091f344 to 4822636 Compare January 26, 2026 10:49
Copy link
Member

@knolleary knolleary left a comment

Choose a reason for hiding this comment

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

Need to think through the potential impact of changing behaviour here.

Comment on lines +200 to +204
if (err) {
node.error(RED._("file.errors.appendfail",{error:err.toString()}),msg);
} else {
nodeSend(msg);
}
Copy link
Member

Choose a reason for hiding this comment

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

I think this will result in a change in behaviour. Previously, it would still do a nodeSend regardless of the error. Now, it will halt the flow in the case of an error.

It's hard to judge if that's okay to change as a fix, rather than a breaking change - we don't know how often this scenario is being hit as we've had no reports on it.

@Dennis-SEG
Copy link
Contributor Author

I've updated the fix based on your suggestion to use the write callback's error argument. Here's the approach:

Static filenames: Use write callback with error argument

node.wstream.write(buf, function(err) {
    if (err) {
        node.error(..., msg);  // correct msg scope
    } else {
        nodeSend(msg);
    }
    done();  // correct done scope
});

Dynamic filenames: Keep using error event (safe because new stream per message)

  • After each write, delete node.wstream is called
  • Next message triggers recreateStream = true
  • Fresh error handler with correct msg/done scope

Error event handler: Now checks filenameType to avoid double-handling

node.wstream.on("error", function(err) {
    if (node.filenameType !== "str" && node.filenameType !== "env") {
        node.error(..., msg);
        done();
    }
});

I verified with Node.js tests that the write callback is called before the error event (as the docs state), so for static filenames:

  1. Write callback handles error with correct scope
  2. Error event fires but handler skips it (filenameType check)

This ensures done() is called exactly once with the correct message context.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Race condition in file node - stale error handler references in append mode

2 participants