From ea51f30a8d765fddd2a21a306e49671a0d30dbc5 Mon Sep 17 00:00:00 2001 From: seb Date: Thu, 1 Oct 2026 22:17:17 +0200 Subject: [PATCH] u --- docs/api/routes/delivery/delete.md | 1 + docs/api/routes/delivery/update.md | 1 + src/api/middleware/logger.js | 8 +++-- src/api/routes/delivery.js | 53 ++++++++++++++++++++++++++---- 4 files changed, 55 insertions(+), 8 deletions(-) diff --git a/docs/api/routes/delivery/delete.md b/docs/api/routes/delivery/delete.md index 9674e21..c1c3cb5 100644 --- a/docs/api/routes/delivery/delete.md +++ b/docs/api/routes/delivery/delete.md @@ -27,6 +27,7 @@ _No content_ | 401 | Unauthorized — `{"error":"…"}` | | 403 | Not authorized — `{"error":"…"}` | | 404 | Delivery not found — `{"error":"…"}` | +| 409 | Delivery in use in ledger — `{"error":"…"}` | --- diff --git a/docs/api/routes/delivery/update.md b/docs/api/routes/delivery/update.md index 97e0557..488b94b 100644 --- a/docs/api/routes/delivery/update.md +++ b/docs/api/routes/delivery/update.md @@ -102,6 +102,7 @@ Updated delivery | 401 | Unauthorized — `{"error":"…"}` | | 403 | Not authorized — `{"error":"…"}` | | 404 | Delivery, supplier, or company not found — `{"error":"…"}` | +| 409 | Delivery lines already booked on ledger — `{"error":"…"}` | --- diff --git a/src/api/middleware/logger.js b/src/api/middleware/logger.js index 3a5ea51..180806f 100644 --- a/src/api/middleware/logger.js +++ b/src/api/middleware/logger.js @@ -20,8 +20,12 @@ function captureResponseBody(res) { const originalSend = res.send.bind(res); res.json = (payload) => { - body = payload; - return originalJson(payload); + let out = payload; + if (res.statusCode >= 500 && payload && typeof payload === 'object' && 'error' in payload) { + out = { ...payload, error: 'Internal server error' }; + } + body = out; + return originalJson(out); }; res.send = (payload) => { diff --git a/src/api/routes/delivery.js b/src/api/routes/delivery.js index bd67282..1da52e9 100644 --- a/src/api/routes/delivery.js +++ b/src/api/routes/delivery.js @@ -172,6 +172,15 @@ function deliveryErrorStatus(error) { if (error.message === 'Invalid JSON in "data" field') return 400; if (error.message === 'Only PDF or text files are accepted as attachments') return 400; if (error.message?.includes('father article') || error.message?.includes('A father article')) return 400; + if ( + error.message === 'Delivery in use in ledger' || + error.message === 'Delivery lines already booked on ledger' || + error.message?.includes('FOREIGN KEY constraint failed') || + error.message?.includes('foreign key constraint') || + error.message?.includes('REFERENCE constraint') || + error.code === 'SQLITE_CONSTRAINT_FOREIGNKEY' || + error.number === 547 + ) return 409; return 500; } @@ -348,7 +357,7 @@ export function register(app, basePath = '') { res.locals.error = error; const status = deliveryErrorStatus(error); if (status === 500) console.error('List deliveries failed:', error); - res.status(status).json({ error: error.message }); + res.status(status).json({ error: status === 500 ? 'Internal server error' : error.message }); } }); @@ -399,7 +408,7 @@ export function register(app, basePath = '') { console.error('[delivery diag] Failed to dump payload:', logErr.message); } } - res.status(status).json({ error: error.message }); + res.status(status).json({ error: status === 500 ? 'Internal server error' : error.message }); } }); @@ -550,6 +559,12 @@ export function register(app, basePath = '') { * application/json: * schema: * $ref: '#/components/schemas/Error' + * 409: + * description: Delivery lines already booked on ledger + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/Error' * delete: * tags: [Delivery] * summary: Delete delivery @@ -591,6 +606,12 @@ export function register(app, basePath = '') { * application/json: * schema: * $ref: '#/components/schemas/Error' + * 409: + * description: Delivery in use in ledger + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/Error' */ app.get(`${basePath}/delivery/:id`, async (req, res) => { const selected = requireSelectedCompany(req); @@ -610,7 +631,7 @@ export function register(app, basePath = '') { res.locals.error = error; const status = deliveryErrorStatus(error); if (status === 500) console.error('Get delivery failed:', error); - res.status(status).json({ error: error.message }); + res.status(status).json({ error: status === 500 ? 'Internal server error' : error.message }); } }); @@ -656,7 +677,21 @@ export function register(app, basePath = '') { if (status === 500) { logStoreError('Update delivery failed', error); } - res.status(status).json({ error: error.message }); + let errorMessage = error.message; + if (status === 500) { + errorMessage = 'Internal server error'; + } else if ( + status === 409 || + error.message === 'Delivery lines already booked on ledger' || + error.message?.includes('FOREIGN KEY constraint failed') || + error.message?.includes('foreign key constraint') || + error.message?.includes('REFERENCE constraint') || + error.code === 'SQLITE_CONSTRAINT_FOREIGNKEY' || + error.number === 547 + ) { + errorMessage = 'Delivery lines are already booked on the ledger and cannot be modified'; + } + res.status(status).json({ error: errorMessage }); } }); @@ -678,7 +713,13 @@ export function register(app, basePath = '') { res.locals.error = error; const status = deliveryErrorStatus(error); if (status === 500) console.error('Delete delivery failed:', error); - res.status(status).json({ error: error.message }); + let errorMessage = error.message; + if (status === 500) { + errorMessage = 'Internal server error'; + } else if (status === 409) { + errorMessage = 'Delivery in use in ledger'; + } + res.status(status).json({ error: errorMessage }); } }); @@ -822,7 +863,7 @@ export function register(app, basePath = '') { res.locals.error = error; const status = deliveryErrorStatus(error); if (status === 500) console.error('Get delivery file failed:', error); - res.status(status).json({ error: error.message }); + res.status(status).json({ error: status === 500 ? 'Internal server error' : error.message }); } };