File size: 2,787 Bytes
e8c33fa
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
const test = require('node:test');
const assert = require('node:assert/strict');

test('asyncController hides internal error messages in production for 5xx', async () => {
  const originalEnv = process.env.NODE_ENV;
  process.env.NODE_ENV = 'production';

  const isProduction = process.env.NODE_ENV === 'production';
  const internalError = new Error('MongoNetworkError: connection refused to cluster0.example.com');
  internalError.statusCode = 503;

  const safeMessage = isProduction && internalError.statusCode >= 500
    ? 'An internal error occurred'
    : internalError.message;

  assert.equal(safeMessage, 'An internal error occurred', 'In production, 5xx errors must use generic message');

  process.env.NODE_ENV = originalEnv;
});

test('asyncController passes through 4xx messages in production', async () => {
  process.env.NODE_ENV = 'production';
  const isProduction = process.env.NODE_ENV === 'production';
  const validationError = new Error('Title is required');
  validationError.statusCode = 400;

  const safeMessage = isProduction && validationError.statusCode >= 500
    ? 'An internal error occurred'
    : validationError.message;

  assert.equal(safeMessage, 'Title is required', '4xx messages must pass through');
  process.env.NODE_ENV = 'development';
});

test('asyncController error response includes success=false and code', async () => {
  const { asyncController } = require('../utils/asyncController');

  let capturedStatus;
  let capturedBody;

  const req = { originalUrl: '/test', method: 'GET', headers: {}, ip: '', user: null, body: {} };
  const res = {
    statusCode: 200,
    headersSent: false,
    status(code) { capturedStatus = code; this.statusCode = code; return this; },
    json(body) { capturedBody = body; },
  };

  const handler = async () => {
    const err = new Error('Validation failed');
    err.statusCode = 400;
    throw err;
  };

  await asyncController(handler)(req, res, () => {});

  assert.equal(capturedStatus, 400);
  assert.equal(capturedBody.success, false);
  assert.equal(capturedBody.code, 'BAD_REQUEST');
  assert.equal(capturedBody.message, 'Validation failed');
});

test('asyncController uses INTERNAL_SERVER_ERROR code for 5xx', async () => {
  const { asyncController } = require('../utils/asyncController');

  let capturedBody;

  const req = { originalUrl: '/test', method: 'GET', headers: {}, ip: '', user: null, body: {} };
  const res = {
    statusCode: 200,
    headersSent: false,
    status() { return this; },
    json(body) { capturedBody = body; },
  };

  const handler = async () => { throw new Error('DB exploded'); };

  await asyncController(handler)(req, res, () => {});

  assert.equal(capturedBody.success, false);
  assert.equal(capturedBody.code, 'INTERNAL_SERVER_ERROR');
});