diff --git a/backend/server.js b/backend/server.js index 54f2827..de3cfba 100644 --- a/backend/server.js +++ b/backend/server.js @@ -35,7 +35,12 @@ app.use( // Same-origin and curl send no Origin header at all. if (!origin) return callback(null, true) if (allowedOrigins.includes(origin)) return callback(null, true) - callback(new Error('Origin not allowed')) + const error = new Error('Origin not allowed') + // Read by the error handler below - a rejected origin is expected, + // routine traffic (bots, scanners, this exact curl test), not a + // server fault, and should neither look like one nor be logged as one. + error.status = 403 + callback(error) }, methods: ['POST'], allowedHeaders: ['Content-Type'], @@ -51,8 +56,15 @@ app.use('/api/audit-request', auditRouter) // Keep internals out of the response body. app.use((error, _req, res, _next) => { - console.error('Unhandled error:', error.message) - res.status(500).json({ success: false, message: 'Internal server error.' }) + const status = error.status ?? 500 + if (status >= 500) { + console.error('Unhandled error:', error.message) + res.status(500).json({ success: false, message: 'Internal server error.' }) + return + } + // Expected rejections (e.g. disallowed CORS origin) - not a server fault, + // so no error-level log line and no generic message. + res.status(status).json({ success: false, message: error.message }) }) const port = Number(env('PORT', '3001'))