-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
p5.js version
1.11.11
What is your operating system?
Mac OS
Web browser and version
Safari 17.6
Actual Behavior
The addProjectToCollection controller (found in server/controllers/collection.controller.js) contains a logic flaw in its Promise handling that leads to a server crash (ERR_HTTP_HEADERS_SENT).
When a validation error occurs (e.g. a collection or a project is not found), the updateCollection function correctly sends a failure response to the client. However, it then returns null to the next block in the Promise chain rather than "short-circuiting" the execution.
addProjectToCollection.js :
First response sent to client here.
Returning 'null' doesn't stop the Promise chain. It passes 'null' to the next .then() block.
function updateCollection([collection, project]) {
if (collection == null) {
sendFailure(404, 'Collection not found');
return null;
}
Then, even if updateCollection returned null, .then(populateReferences) runs.
Second response occurs when .then(sendSuccess), attempts to send 200OK and crash.
return Promise.all([collectionPromise, projectPromise])
.then(updateCollection)
.then(populateReferences)
.then(sendSuccess)
.catch(sendFailure);
Error in Terminal:
node:_http_outgoing:655
throw new ERR_HTTP_HEADERS_SENT('set');
^
Error: Cannot set headers after they are sent to the client
Expected Behavior
When a resource (Collection or Project) is not found, the server should respond with a 404 Not Found and terminate the request lifecycle immediately.
The Promise chain should be short-circuited so that subsequent .then() blocks (like populateReferences and sendSuccess) are never executed after a failure response has been sent. The Node process should remain operational, and no ERR_HTTP_HEADERS_SENT error should be triggered.
Steps to reproduce
Steps:
This bug is triggered by a race condition where the Frontend UI becomes "stale" due to actions in another session/tab. For example:
- Ensure user is logged in
- Open the p5.js Web Editor in two separate browser tabs (Tab A and Tab B).
- In Tab A: Open the "Add to Collection" modal for any sketch. The list of existing collections is displayed, if none, create one.
- In Tab B, delete the collection that you intend to add the sketch to.
- Back in Tab, click the button to add the sketch to that (now deleted) collection.
Observed Result: The server identifies the collection is missing, sends a 404, but then fails to stop execution, attempts a second response, and crashes the backend process.
Also happens when: user has a sketch open in Tab A, deletes it in Tab B, and then attempts to add the now deleted sketch from Tab A to a collection.