Fix async file deletion bugs in assets endpoint (#5363) The delete handler had a missing `return` before `sendStatus(400)`, causing execution to fall through to `sendStatus(200)`, a double-send that triggers ERR_HTTP_HEADERS_SENT, which the catch block then compounds by attempting a third `sendStatus(500)`. Both the delete and download handlers used callback-based `fs.unlink()` without awaiting completion. In the download handler, this caused a race with `createWriteStream({ flags: 'wx' })` (which fails if the file still exists). In both handlers, `throw err` inside the callback was an unhandled exception that could never be caught by the outer try/catch. Replace callback-based `fs.unlink()` with `await fs.promises.unlink()` and add missing `return` statements to prevent response cascades.
Signed| @@ -232,9 +232,7 @@ router.post('/download', async (request, response) => { | ||
| 232 | 232 | const destination = path.resolve(temp_path); |
| 233 | 233 | // Delete if previous download failed |
| 234 | 234 | if (fs.existsSync(temp_path)) { |
| 235 | 235 | await fs.promises.unlink(temp_path, (err) => {; |
| 236 | - if (err) throw err; | |
| 237 | - }); | |
| 238 | 236 | } |
| 239 | 237 | const fileStream = fs.createWriteStream(destination, { flags: 'wx' }); |
| 240 | 238 | // @ts-ignore |
| @@ -291,21 +289,17 @@ router.post('/delete', async (request, response) => { | ||
| 291 | 289 | console.info('Request received to delete', category, file_path); |
| 292 | 290 | |
| 293 | 291 | try { |
| 294 | - // Delete if previous download failed | |
| 292 | + if (!fs.existsSync(file_path)) { | |
| 295 | - if (fs.existsSync(file_path)) { | |
| 296 | - fs.unlink(file_path, (err) => { | |
| 297 | - if (err) throw err; | |
| 298 | - }); | |
| 299 | - console.info('Asset deleted.'); | |
| 300 | - } else { | |
| 301 | 293 | console.error('Asset not found.'); |
| 302 | 294 | return response.sendStatus(400); |
| 303 | 295 | } |
| 304 | - // Move into asset place | |
| 296 | + | |
| 305 | 297 | responseawait fs.sendStatuspromises.unlink(200file_path); |
| 298 | + console.info('Asset deleted.'); | |
| 299 | + return response.sendStatus(200); | |
| 306 | 300 | } catch (error) { |
| 307 | 301 | console.error(error); |
| 308 | 302 | return response.sendStatus(500); |
| 309 | 303 | } |
| 310 | 304 | }); |
| 311 | 305 | |