• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

opengovsg / FormSG / 15200710067

23 May 2025 02:23AM UTC coverage: 72.083% (-0.06%) from 72.142%
15200710067

push

github

GitHub
fix(deps): bump zod from 3.25.17 to 3.25.20 in /shared (#8411)

2895 of 4897 branches covered (59.12%)

Branch coverage included in aggregate %.

10426 of 13583 relevant lines covered (76.76%)

45.96 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.33
/src/app/modules/core/core.errors.ts
1
import { setErrorCode } from '../datadog/datadog.utils'
242✔
2

3
/**
4
 * Global Error Code Registry
5
 *
6
 * - [10xxxx] FormSG Errors
7
 * - [11xxxx] Auth Errors
8
 * - [12xxxx] Database Errors
9
 * - [13xxxx] Payment Errors
10
 * - [14xxxx] Communication Channel Errors
11
 * - [15xxxx] Verification Errors
12
 * - [19xxxx] Other Errors
13
 * Group in general categories for easy datadog queries
14
 * Group in sub groups for easy allocation, identification with screaming snake case prefix of the module
15
 */
16
export enum ErrorCodes {
242✔
17
  // [10xxxx] FormSG Errors ----------------------------------------------------
18
  // [100000 - 100099] General Form Errors (/modules/form)
19
  FORM_PRIVATE_FORM = 100000,
242✔
20
  FORM_NOT_FOUND = 100001,
242✔
21
  FORM_DELETED = 100002,
242✔
22
  FORM_FORBIDDEN_FORM = 100003,
242✔
23
  FORM_TRANSFER_OWNERSHIP = 100004,
242✔
24
  FORM_LOGIC_NOT_FOUND = 100005,
242✔
25
  FORM_AUTH_TYPE_MISMATCH = 100006,
242✔
26
  FORM_AUTH_NO_ESRVC_ID = 100007,
242✔
27
  FORM_RESPONDENT_NOT_WHITELISTED = 100008,
242✔
28
  FORM_RESPONDENT_SINGLE_SUBMISSION_VALIDATION_FAILED = 100009,
242✔
29
  FORM_UNEXPECTED_WHITELIST_SETTING_NOT_FOUND = 100010,
242✔
30
  FORM_INVALID_RESPONSE_MODE = 100011,
242✔
31
  // [100100 - 100199] Admin Form Errors (/modules/form/admin-form)
32
  ADMIN_FORM_INVALID_FILE_TYPE = 100100,
242✔
33
  ADMIN_FORM_EDIT_FIELD = 100101,
242✔
34
  ADMIN_FORM_FIELD_NOT_FOUND = 100102,
242✔
35
  ADMIN_FORM_INVALID_COLLABORATOR = 100103,
242✔
36
  ADMIN_FORM_PAYMENT_CHANNEL_NOT_FOUND = 100104,
242✔
37
  ADMIN_FORM_GOGOV = 100105,
242✔
38
  ADMIN_FORM_GOGOV_VALIDATION = 100106,
242✔
39
  ADMIN_FORM_GOGOV_ALREADY_EXIST = 100107,
242✔
40
  ADMIN_FORM_GOGOV_REQUEST_LIMIT = 100108,
242✔
41
  ADMIN_FORM_GOGOV_BAD_GATEWAY = 100109,
242✔
42
  ADMIN_FORM_GOGOV_SERVER = 100110,
242✔
43
  ADMIN_FORM_INVALID_APPROVAL_FIELD_TYPE = 100111,
242✔
44
  ADMIN_FORM_MODEL_RESPONSE_INVALID_SYNTAX = 100112,
242✔
45
  ADMIN_FORM_MODEL_RESPONSE_INVALID_SCHEMA_FORMAT = 100113,
242✔
46
  ADMIN_FORM_MODEL_RESPONSE_FAILURE = 100114,
242✔
47
  ADMIN_FORM_MODEL_GET_CLIENT_FAILURE = 100115,
242✔
48
  // [100200 - 100299] Submission Errors (/modules/submission)
49
  SUBMISSION_CONFLICT = 100200,
242✔
50
  SUBMISSION_NOT_FOUND = 100201,
242✔
51
  SUBMISSION_PENDING_NOT_FOUND = 100202,
242✔
52
  SUBMISSION_INVALID_TYPE = 100203,
242✔
53
  SUBMISSION_INVALID_ENCODING = 100204,
242✔
54
  SUBMISSION_PROCESSING = 100205,
242✔
55
  SUBMISSION_VALIDATE_FIELD = 100206,
242✔
56
  SUBMISSION_VALIDATE_FIELD_V3 = 100702,
242✔
57
  SUBMISSION_SEND_EMAIL_CONFIRMATION = 100207,
242✔
58
  SUBMISSION_WRONG_RESPONSE_MODE = 100208,
242✔
59
  SUBMISSION_ATTACHMENT_TOO_LARGE = 100209,
242✔
60
  SUBMISSION_INVALID_FILE_EXTENSION = 100210,
242✔
61
  SUBMISSION_FAILED = 100211,
242✔
62
  SUBMISSION_INVALID_FIELD_ID = 100212,
242✔
63
  SUBMISSION_ATTACHMENT_SIZE_LIMIT_EXCEEDED = 100213,
242✔
64
  SUBMISSION_FEATURE_DISABLED = 100214,
242✔
65
  SUBMISSION_INVALID_FILE_KEY = 100215,
242✔
66
  SUBMISSION_VIRUS_SCAN_FAILED = 100216,
242✔
67
  SUBMISSION_JSON_PARSE_FAILED = 100217,
242✔
68
  SUBMISSION_DOWNLOAD_CLEAN_FILE_FAILED = 100218,
242✔
69
  SUBMISSION_PARSE_VIRUS_SCANNER_LAMBDA_PAYLOAD = 100219,
242✔
70
  SUBMISSION_MALICIOUS_FILE_DETECTED = 100220,
242✔
71
  SUBMISSION_INVALID_WORKFLOW_TYPE = 100221,
242✔
72
  SUBMISSION_ATTACHMENT_UPLOAD = 100222,
242✔
73
  SUBMISSION_EMAIL_HASH = 100223, // Email submission error (email mode deprecated soon)
242✔
74
  SUBMISSION_EXPECTED_RESPONSE_NOT_FOUND = 100224,
242✔
75
  SUBMISSION_SAVE_FAILURE = 100225,
242✔
76
  SUBMISSION_MRF_REMINDER_INVALID_PENDING_STEP = 100226,
242✔
77
  SUBMISSION_MRF_REMINDER_RECIPIENT_EMAILS_EMPTY = 100227,
242✔
78
  SUBMISSION_GD_INVALID_FILE_KEY = 100228,
242✔
79
  SUBMISSION_GD_VIRUS_SCAN_FAILED = 100229,
242✔
80
  SUBMISSION_GD_DOWNLOAD_CLEAN_FILE_FAILED = 100230,
242✔
81
  SUBMISSION_GD_PARSE_VIRUS_SCANNER_LAMBDA_PAYLOAD = 100231,
242✔
82
  SUBMISSION_GD_MALICIOUS_FILE_DETECTED = 100232,
242✔
83
  // [100300 - 100399] Receiver Errors (/modules/submission/receiver)
84
  RECEIVER_INITIALISE_MULTIPART_RECEIVER = 100301,
242✔
85
  RECEIVER_MULTIPART_CONTENT_LIMIT = 100302,
242✔
86
  RECEIVER_MULTIPART_CONTENT_PARSING = 100303,
242✔
87
  RECEIVER_MULTIPART_ERROR = 100304,
242✔
88
  // [100400 - 100499] Encrypt Submission Errors (/modules/submission/encrypt-submission)
89
  ENCRYPT_FORMSG_REQ_BODY_EXISTS = 100400,
242✔
90
  ENCRYPT_ENCRYPTED_PAYLOAD_EXISTS = 100401,
242✔
91
  // [100500 - 100599] Feedback Errors (/modules/feedback)
92
  FEEDBACK_INVALID_SUBMISSION_ID = 100500,
242✔
93
  FEEDBACK_DUPLICATE_SUBMISSION = 100501,
242✔
94
  // [100600 - 100699] Admin Feedback Errors (/modules/admin-feedback)
95
  ADMIN_FEEDBACK_MISSING = 100600,
242✔
96
  // [100700 - 100799] Workspace Errors (/modules/workspace)
97
  WORKSPACE_NOT_FOUND = 100700,
242✔
98
  WORKSPACE_FORBIDDEN = 100701,
242✔
99
  // End FormSG Errors ---------------------------------------------------------
100

101
  // [11xxxx] Auth Errors ------------------------------------------------------
102
  // [110000 - 110099] General Auth Errors (/modules/auth)
103
  AUTH_INVALID_DOMAIN = 110000,
242✔
104
  AUTH_INVALID_OTP = 110001,
242✔
105
  AUTH_INVALID_TOKEN = 110002,
242✔
106
  AUTH_MISSING_TOKEN = 110003,
242✔
107
  AUTH_UNAUTHORIZED = 110004,
242✔
108
  // [110100 - 110199] SPCP Errors (/modules/spcp)
109
  SPCP_CREATE_REDIRECT_URL = 110100,
242✔
110
  SPCP_VERIFY_JWT = 110101,
242✔
111
  SPCP_MISSING_ATTRIBUTES = 110102,
242✔
112
  SPCP_INVALID_JWT = 110103,
242✔
113
  SPCP_MISSING_JWT = 110104,
242✔
114
  SPCP_INVALID_ID_TOKEN = 110105,
242✔
115
  SPCP_INVALID_STATE = 110106,
242✔
116
  SPCP_CREATE_JWT = 110107,
242✔
117
  SPCP_EXCHANGE_AUTH_TOKEN = 110108,
242✔
118
  // [110200 - 110299] SPCP OIDC Errors (/modules/spcp)
119
  SPCP_OIDC_CREATE_AUTHORISATION_URL = 110200,
242✔
120
  SPCP_OIDC_CREATE_JWT = 110201,
242✔
121
  SPCP_OIDC_GET_SIGNING_KEY = 110202,
242✔
122
  SPCP_OIDC_GET_DECRYPTION_KEY = 110203,
242✔
123
  SPCP_OIDC_GET_VERIFICATION_KEY = 110204,
242✔
124
  SPCP_OIDC_INVALID_ID_TOKEN = 110205,
242✔
125
  SPCP_OIDC_JWK_SHAPE_INVALID = 110206,
242✔
126
  SPCP_OIDC_MISSING_ID_TOKEN = 110207,
242✔
127
  SPCP_OIDC_INVALID_VERIFICATION_KEY = 110208,
242✔
128
  SPCP_OIDC_EXCHANGE_AUTH_TOKEN = 110209,
242✔
129
  // [110300 - 110399] MyInfo Errors (/modules/myinfo)
130
  MYINFO_CIRCUIT_BREAKER = 110300,
242✔
131
  MYINFO_FETCH = 110301,
242✔
132
  MYINFO_HASHING = 110302,
242✔
133
  MYINFO_MISSING_HASH = 110303,
242✔
134
  MYINFO_HASH_DID_NOT_MATCH = 110304,
242✔
135
  MYINFO_PARSE_RELAY_STATE = 110305,
242✔
136
  MYINFO_MISSING_LOGIN_COOKIE = 110306,
242✔
137
  MYINFO_INVALID_LOGIN_COOKIE = 110307,
242✔
138
  MYINFO_INVALID_AUTH_CODE_COOKIE = 110308,
242✔
139
  MYINFO_COOKIE_STATE = 110309,
242✔
140
  // [110400 - 110499] Sgid Errors (/modules/sgid)
141
  SGID_CREATE_REDIRECT_URL = 110400,
242✔
142
  SGID_INVALID_STATE = 110401,
242✔
143
  SGID_FETCH_ACCESS_TOKEN = 110402,
242✔
144
  SGID_FETCH_USER_INFO = 110403,
242✔
145
  SGID_MALFORMED_MYINFO_COOKIE = 110404,
242✔
146
  SGID_VERIFY_JWT = 110405,
242✔
147
  SGID_INVALID_JWT = 110406,
242✔
148
  SGID_MISSING_JWT = 110407,
242✔
149
  // End of Auth Errors --------------------------------------------------------
150

151
  // [12xxxx] Database Errors (/modules/core) ----------------------------------
152
  DATABASE_ERROR = 120000,
242✔
153
  DATABASE_VALIDATION = 120001,
242✔
154
  DATABASE_CONFLICT = 120002,
242✔
155
  DATABASE_PAYLOAD_SIZE = 120003,
242✔
156
  DATABASE_DUPLICATE_KEY = 120004,
242✔
157
  DATABASE_WRITE_CONFLICT = 120005,
242✔
158
  // End of Database Errors ----------------------------------------------------
159

160
  // [13xxxx] Payment Errors ---------------------------------------------------
161
  // [130000 - 130099] General Payment Errors (/modules/payments)
162
  PAYMENT_INVALID_AMOUNT = 130000,
242✔
163
  PAYMENT_NOT_FOUND = 130001,
242✔
164
  PAYMENT_CONFIRMED_PAYMENT_NOT_FOUND = 130002,
242✔
165
  PAYMENT_ALREADY_CONFIRMED = 130003,
242✔
166
  PAYMENT_ACCOUNT_INFORMATION = 130004,
242✔
167
  PAYMENT_INVALID_PAYMENT_PRODUCTS = 130005,
242✔
168
  PAYMENT_CONFIGURATION = 130006,
242✔
169
  // [130100 - 130199] Stripe Errors (/modules/payments)
170
  PAYMENT_STRIPE_SUCCESSFUL_CHARGE_NOT_FOUND = 130100,
242✔
171
  PAYMENT_STRIPE_TRANSACTION_FEE_NOT_FOUND = 130101,
242✔
172
  PAYMENT_STRIPE_MALFORMED_CHARGE_OBJECT = 130102,
242✔
173
  PAYMENT_STRIPE_MALFORMED_EVENT_OBJECT = 130103,
242✔
174
  PAYMENT_STRIPE_METADATA_INVALID = 130104,
242✔
175
  PAYMENT_STRIPE_METADATA_VALID_PAYMENT_ID_NOT_FOUND = 130105,
242✔
176
  PAYMENT_STRIPE_METADATA_INCORRECT_ENV = 130106,
242✔
177
  PAYMENT_STRIPE_FETCH_ERROR = 130107,
242✔
178
  PAYMENT_STRIPE_ACCOUNT_ERROR = 130108,
242✔
179
  PAYMENT_STRIPE_COMPUTE_PAYMENT_STATE = 130109,
242✔
180
  // [130200 - 130299] Payment Proof Errors (/modules/payments)
181
  PAYMENT_PROOF_INVOICE_PDF_GENERATION = 130200,
242✔
182
  PAYMENT_PROOF_UPLOAD_S3 = 130201,
242✔
183
  PAYMENT_PROOF_PRESIGN_S3 = 130202,
242✔
184
  // [130300 - 130399] Billing Errors (/modules/billing)
185
  BILLING_FORM_HAS_NO_AUTH = 130300,
242✔
186
  // End of Payment Errors -----------------------------------------------------
187

188
  // [14xxxx] Communication Channel Errors (SMS, Email, Webhook) ---------------
189
  // [140000 - 140099] SMS Errors (/services/postman-sms)
190
  POSTMAN_SMS_SEND = 140000,
242✔
191
  POSTMAN_INVALID_NUMBER = 140001,
242✔
192
  // [140100 - 140199] Mail Errors (/services/mail)
193
  MAIL_SEND_ERROR = 140100,
242✔
194
  MAIL_GENERATION_ERROR = 140101,
242✔
195
  // [140200 - 140299] Webhook Errors (/modules/webhook)
196
  WEBHOOK_VALIDATION = 140200,
242✔
197
  WEBHOOK_FAILED_WITH_PRESIGNED_URL_GENERATION = 140201,
242✔
198
  WEBHOOK_FAILED_WITH_UNKNOWN_ERROR = 140202,
242✔
199
  WEBHOOK_FAILED_WITH_AXIOS_ERROR = 140203,
242✔
200
  WEBHOOK_QUEUE_MESSAGE_PARSING_ERROR = 140204,
242✔
201
  WEBHOOK_NO_MORE_RETRIES = 140205,
242✔
202
  WEBHOOK_PUSH_TO_QUEUE = 140206,
242✔
203
  WEBHOOK_RETRIES_NOT_ENABLED = 140207,
242✔
204
  // [140300 - 140399] Bounce Errors (/modules/bounce)
205
  BOUNCE_INVALID_NOTIFCATION = 140300,
242✔
206
  BOUNCE_SEND_BOUNCE_SMS_NOTIFICATION = 140301,
242✔
207
  BOUNCE_MISSING_EMAIL_HEADERS = 140302,
242✔
208
  BOUNCE_PARSE_NOTIFICATION = 140303,
242✔
209
  // End of Communication Channel Errors ---------------------------------------
210

211
  // [15xxxx] Verification Errors ----------------------------------------------
212
  // [150000 - 150099] General Verification Errors (/modules/verification)
213
  VERIFICATION_TRANSACTION_NOT_FOUND = 150000,
242✔
214
  VERIFICATION_FIELD_NOT_FOUND_IN_TRANSACTION = 150001,
242✔
215
  VERIFICATION_TRANSACTION_EXPIRED = 150002,
242✔
216
  VERIFICATION_OTP_EXPIRED = 150003,
242✔
217
  VERIFICATION_MISSING_HASH_DATA = 150004,
242✔
218
  VERIFICATION_OTP_RETRY_EXCEEDED = 150005,
242✔
219
  VERIFICATION_WRONG_OTP = 150006,
242✔
220
  VERIFICATION_WAIT_FOR_OTP = 150007,
242✔
221
  VERIFICATION_OTP_REQUEST_COUNT_EXCEEDED = 150008,
242✔
222
  VERIFICATION_NON_VERIFIED_FIELD_TYPE = 150009,
242✔
223
  VERIFICATION_SMS_LIMIT_EXCEEDED = 150010,
242✔
224
  VERIFICATION_OTP_REQUEST_ERROR = 150011,
242✔
225
  // [150100 - 150199] Captcha Errors (/services/captcha)
226
  CAPTCHA_CONNECTION = 150100,
242✔
227
  CAPTCHA_VERIFY = 150101,
242✔
228
  CAPTCHA_MISSING = 150102,
242✔
229
  // [150200 - 150299] Turnstile Errors (/services/turnstile)
230
  TURNSTILE_CONNECTION = 150200,
242✔
231
  TURNSTILE_RESPONSE_ERROR = 150201,
242✔
232
  TURNSTILE_MISSING = 150202,
242✔
233
  // End of Verification Errors ------------------------------------------------
234

235
  // [19xxxx] Other Errors -----------------------------------------------------
236
  // [190000 - 190099] Core Errors (/modules/core)
237
  MALFORMED_PARAMETERS = 190000,
242✔
238
  EMPTY_ERROR_FIELD = 190001,
242✔
239
  SECRETS_MANAGER = 190002,
242✔
240
  SECRETS_MANAGER_NOT_FOUND = 190003,
242✔
241
  SECRETS_MANAGER_CONFLICT = 190004,
242✔
242
  TWILIO_CACHE = 190005,
242✔
243
  // [190100 - 190199] User Errors (/modules/user)
244
  USER_INVALID_OTP = 190100,
242✔
245
  USER_MISSING = 190101,
242✔
246
  // [190200 - 190299] Verified Content Errors (/modules/verified-content)
247
  VERIFIED_CONTENT_MALFORMED = 190200,
242✔
248
  VERIFIED_CONTENT_ENCRYPT_FAILURE = 190201,
242✔
249
  // End of Other Errors -------------------------------------------------------
250
}
251

252
/**
253
 * A custom base error class that encapsulates the name, message, status code,
254
 * and logging meta string (if any) for the error.
255
 */
256
export class ApplicationError extends Error {
242✔
257
  /**
258
   * Meta object to be logged by the application logger, if any.
259
   */
260
  meta?: unknown
261
  // FormSG Business Logic errors, not to be confused with HTTP Status Codes
262
  code?: number
263

264
  constructor(message?: string, meta?: unknown, errorCode?: number) {
265
    super()
2,097✔
266

267
    this.name = this.constructor.name
2,097✔
268
    this.message = message || 'Something went wrong. Please try again.'
2,097✔
269
    Error.captureStackTrace(this, this.constructor)
2,097✔
270

271
    this.meta = meta
2,097✔
272
    this.code = errorCode
2,097✔
273

274
    if (this.code) {
2,097✔
275
      setErrorCode(this)
2,027✔
276
    }
277
  }
278
}
279

280
export class DatabaseError extends ApplicationError {
242✔
281
  constructor(message?: string) {
282
    super(message, undefined, ErrorCodes.DATABASE_ERROR)
245✔
283
  }
284
}
285

286
export class DatabaseValidationError extends ApplicationError {
242✔
287
  constructor(message: string) {
288
    super(message, undefined, ErrorCodes.DATABASE_VALIDATION)
18✔
289
  }
290
}
291

292
export class DatabaseConflictError extends ApplicationError {
242✔
293
  constructor(message: string) {
294
    super(message, undefined, ErrorCodes.DATABASE_CONFLICT)
9✔
295
  }
296
}
297

298
export class DatabasePayloadSizeError extends ApplicationError {
242✔
299
  constructor(message: string) {
300
    super(message, undefined, ErrorCodes.DATABASE_PAYLOAD_SIZE)
11✔
301
  }
302
}
303

304
export class DatabaseDuplicateKeyError extends ApplicationError {
242✔
305
  constructor(message: string) {
306
    super(message, undefined, ErrorCodes.DATABASE_DUPLICATE_KEY)
1✔
307
  }
308
}
309

310
export class DatabaseWriteConflictError extends ApplicationError {
242✔
311
  constructor(message: string) {
312
    super(message, undefined, ErrorCodes.DATABASE_WRITE_CONFLICT)
×
313
  }
314
}
315

316
export class SecretsManagerError extends ApplicationError {
242✔
317
  constructor(message?: string) {
318
    super(message, undefined, ErrorCodes.SECRETS_MANAGER)
×
319
  }
320
}
321

322
export class SecretsManagerNotFoundError extends ApplicationError {
242✔
323
  constructor(message: string) {
324
    super(message, undefined, ErrorCodes.SECRETS_MANAGER_NOT_FOUND)
×
325
  }
326
}
327

328
export class SecretsManagerConflictError extends ApplicationError {
242✔
329
  constructor(message: string) {
330
    super(message, undefined, ErrorCodes.SECRETS_MANAGER_CONFLICT)
×
331
  }
332
}
333

334
/**
335
 * Union of all possible database errors
336
 */
337
export type PossibleDatabaseError =
338
  | DatabaseError
339
  | DatabaseValidationError
340
  | DatabaseConflictError
341
  | DatabasePayloadSizeError
342
  | DatabaseDuplicateKeyError
343
  | DatabaseWriteConflictError
344

345
export class MalformedParametersError extends ApplicationError {
242✔
346
  constructor(message: string, meta?: unknown) {
347
    super(message, meta, ErrorCodes.MALFORMED_PARAMETERS)
16✔
348
  }
349
}
350

351
/**
352
 * A custom error class returned when a method explicitly returns a list of errors
353
 * but the list itself is empty.
354
 */
355
export class EmptyErrorFieldError extends ApplicationError {
242✔
356
  constructor(message = 'Errors were returned but list is empty.') {
×
357
    super(message, undefined, ErrorCodes.EMPTY_ERROR_FIELD)
×
358
  }
359
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc