strong-tie/inbound-calls
0
1'use strict'2 3const { test } = require('node:test')4const errors = require('../../lib/errors')5const { readFileSync } = require('node:fs')6const { resolve } = require('node:path')7 8const expectedErrors = 849 10test(`should expose ${expectedErrors} errors`, t => {11 t.plan(1)12 const exportedKeys = Object.keys(errors)13 let counter = 014 for (const key of exportedKeys) {15 if (errors[key].name === 'FastifyError') {16 counter++17 }18 }19 t.assert.strictEqual(counter, expectedErrors)20})21 22test('ensure name and codes of Errors are identical', t => {23 t.plan(expectedErrors)24 const exportedKeys = Object.keys(errors)25 for (const key of exportedKeys) {26 if (errors[key].name === 'FastifyError') {27 t.assert.strictEqual(key, new errors[key]().code, key)28 }29 }30})31 32test('FST_ERR_NOT_FOUND', t => {33 t.plan(5)34 const error = new errors.FST_ERR_NOT_FOUND()35 t.assert.strictEqual(error.name, 'FastifyError')36 t.assert.strictEqual(error.code, 'FST_ERR_NOT_FOUND')37 t.assert.strictEqual(error.message, 'Not Found')38 t.assert.strictEqual(error.statusCode, 404)39 t.assert.ok(error instanceof Error)40})41 42test('FST_ERR_OPTIONS_NOT_OBJ', t => {43 t.plan(5)44 const error = new errors.FST_ERR_OPTIONS_NOT_OBJ()45 t.assert.strictEqual(error.name, 'FastifyError')46 t.assert.strictEqual(error.code, 'FST_ERR_OPTIONS_NOT_OBJ')47 t.assert.strictEqual(error.message, 'Options must be an object')48 t.assert.strictEqual(error.statusCode, 500)49 t.assert.ok(error instanceof TypeError)50})51 52test('FST_ERR_QSP_NOT_FN', t => {53 t.plan(5)54 const error = new errors.FST_ERR_QSP_NOT_FN()55 t.assert.strictEqual(error.name, 'FastifyError')56 t.assert.strictEqual(error.code, 'FST_ERR_QSP_NOT_FN')57 t.assert.strictEqual(error.message, "querystringParser option should be a function, instead got '%s'")58 t.assert.strictEqual(error.statusCode, 500)59 t.assert.ok(error instanceof TypeError)60})61 62test('FST_ERR_SCHEMA_CONTROLLER_BUCKET_OPT_NOT_FN', t => {63 t.plan(5)64 const error = new errors.FST_ERR_SCHEMA_CONTROLLER_BUCKET_OPT_NOT_FN()65 t.assert.strictEqual(error.name, 'FastifyError')66 t.assert.strictEqual(error.code, 'FST_ERR_SCHEMA_CONTROLLER_BUCKET_OPT_NOT_FN')67 t.assert.strictEqual(error.message, "schemaController.bucket option should be a function, instead got '%s'")68 t.assert.strictEqual(error.statusCode, 500)69 t.assert.ok(error instanceof TypeError)70})71 72test('FST_ERR_SCHEMA_ERROR_FORMATTER_NOT_FN', t => {73 t.plan(5)74 const error = new errors.FST_ERR_SCHEMA_ERROR_FORMATTER_NOT_FN()75 t.assert.strictEqual(error.name, 'FastifyError')76 t.assert.strictEqual(error.code, 'FST_ERR_SCHEMA_ERROR_FORMATTER_NOT_FN')77 t.assert.strictEqual(error.message, "schemaErrorFormatter option should be a non async function. Instead got '%s'.")78 t.assert.strictEqual(error.statusCode, 500)79 t.assert.ok(error instanceof TypeError)80})81 82test('FST_ERR_AJV_CUSTOM_OPTIONS_OPT_NOT_OBJ', t => {83 t.plan(5)84 const error = new errors.FST_ERR_AJV_CUSTOM_OPTIONS_OPT_NOT_OBJ()85 t.assert.strictEqual(error.name, 'FastifyError')86 t.assert.strictEqual(error.code, 'FST_ERR_AJV_CUSTOM_OPTIONS_OPT_NOT_OBJ')87 t.assert.strictEqual(error.message, "ajv.customOptions option should be an object, instead got '%s'")88 t.assert.strictEqual(error.statusCode, 500)89 t.assert.ok(error instanceof TypeError)90})91 92test('FST_ERR_AJV_CUSTOM_OPTIONS_OPT_NOT_ARR', t => {93 t.plan(5)94 const error = new errors.FST_ERR_AJV_CUSTOM_OPTIONS_OPT_NOT_ARR()95 t.assert.strictEqual(error.name, 'FastifyError')96 t.assert.strictEqual(error.code, 'FST_ERR_AJV_CUSTOM_OPTIONS_OPT_NOT_ARR')97 t.assert.strictEqual(error.message, "ajv.plugins option should be an array, instead got '%s'")98 t.assert.strictEqual(error.statusCode, 500)99 t.assert.ok(error instanceof TypeError)100})101 102test('FST_ERR_CTP_ALREADY_PRESENT', t => {103 t.plan(5)104 const error = new errors.FST_ERR_CTP_ALREADY_PRESENT()105 t.assert.strictEqual(error.name, 'FastifyError')106 t.assert.strictEqual(error.code, 'FST_ERR_CTP_ALREADY_PRESENT')107 t.assert.strictEqual(error.message, "Content type parser '%s' already present.")108 t.assert.strictEqual(error.statusCode, 500)109 t.assert.ok(error instanceof Error)110})111 112test('FST_ERR_CTP_INVALID_TYPE', t => {113 t.plan(5)114 const error = new errors.FST_ERR_CTP_INVALID_TYPE()115 t.assert.strictEqual(error.name, 'FastifyError')116 t.assert.strictEqual(error.code, 'FST_ERR_CTP_INVALID_TYPE')117 t.assert.strictEqual(error.message, 'The content type should be a string or a RegExp')118 t.assert.strictEqual(error.statusCode, 500)119 t.assert.ok(error instanceof TypeError)120})121 122test('FST_ERR_CTP_EMPTY_TYPE', t => {123 t.plan(5)124 const error = new errors.FST_ERR_CTP_EMPTY_TYPE()125 t.assert.strictEqual(error.name, 'FastifyError')126 t.assert.strictEqual(error.code, 'FST_ERR_CTP_EMPTY_TYPE')127 t.assert.strictEqual(error.message, 'The content type cannot be an empty string')128 t.assert.strictEqual(error.statusCode, 500)129 t.assert.ok(error instanceof TypeError)130})131 132test('FST_ERR_CTP_INVALID_HANDLER', t => {133 t.plan(5)134 const error = new errors.FST_ERR_CTP_INVALID_HANDLER()135 t.assert.strictEqual(error.name, 'FastifyError')136 t.assert.strictEqual(error.code, 'FST_ERR_CTP_INVALID_HANDLER')137 t.assert.strictEqual(error.message, 'The content type handler should be a function')138 t.assert.strictEqual(error.statusCode, 500)139 t.assert.ok(error instanceof TypeError)140})141 142test('FST_ERR_CTP_INVALID_PARSE_TYPE', t => {143 t.plan(5)144 const error = new errors.FST_ERR_CTP_INVALID_PARSE_TYPE()145 t.assert.strictEqual(error.name, 'FastifyError')146 t.assert.strictEqual(error.code, 'FST_ERR_CTP_INVALID_PARSE_TYPE')147 t.assert.strictEqual(error.message, "The body parser can only parse your data as 'string' or 'buffer', you asked '%s' which is not supported.")148 t.assert.strictEqual(error.statusCode, 500)149 t.assert.ok(error instanceof TypeError)150})151 152test('FST_ERR_CTP_BODY_TOO_LARGE', t => {153 t.plan(5)154 const error = new errors.FST_ERR_CTP_BODY_TOO_LARGE()155 t.assert.strictEqual(error.name, 'FastifyError')156 t.assert.strictEqual(error.code, 'FST_ERR_CTP_BODY_TOO_LARGE')157 t.assert.strictEqual(error.message, 'Request body is too large')158 t.assert.strictEqual(error.statusCode, 413)159 t.assert.ok(error instanceof RangeError)160})161 162test('FST_ERR_CTP_INVALID_MEDIA_TYPE', t => {163 t.plan(5)164 const error = new errors.FST_ERR_CTP_INVALID_MEDIA_TYPE()165 t.assert.strictEqual(error.name, 'FastifyError')166 t.assert.strictEqual(error.code, 'FST_ERR_CTP_INVALID_MEDIA_TYPE')167 t.assert.strictEqual(error.message, 'Unsupported Media Type: %s')168 t.assert.strictEqual(error.statusCode, 415)169 t.assert.ok(error instanceof Error)170})171 172test('FST_ERR_CTP_INVALID_CONTENT_LENGTH', t => {173 t.plan(5)174 const error = new errors.FST_ERR_CTP_INVALID_CONTENT_LENGTH()175 t.assert.strictEqual(error.name, 'FastifyError')176 t.assert.strictEqual(error.code, 'FST_ERR_CTP_INVALID_CONTENT_LENGTH')177 t.assert.strictEqual(error.message, 'Request body size did not match Content-Length')178 t.assert.strictEqual(error.statusCode, 400)179 t.assert.ok(error instanceof RangeError)180})181 182test('FST_ERR_CTP_EMPTY_JSON_BODY', t => {183 t.plan(5)184 const error = new errors.FST_ERR_CTP_EMPTY_JSON_BODY()185 t.assert.strictEqual(error.name, 'FastifyError')186 t.assert.strictEqual(error.code, 'FST_ERR_CTP_EMPTY_JSON_BODY')187 t.assert.strictEqual(error.message, "Body cannot be empty when content-type is set to 'application/json'")188 t.assert.strictEqual(error.statusCode, 400)189 t.assert.ok(error instanceof Error)190})191 192test('FST_ERR_CTP_INSTANCE_ALREADY_STARTED', t => {193 t.plan(5)194 const error = new errors.FST_ERR_CTP_INSTANCE_ALREADY_STARTED()195 t.assert.strictEqual(error.name, 'FastifyError')196 t.assert.strictEqual(error.code, 'FST_ERR_CTP_INSTANCE_ALREADY_STARTED')197 t.assert.strictEqual(error.message, 'Cannot call "%s" when fastify instance is already started!')198 t.assert.strictEqual(error.statusCode, 400)199 t.assert.ok(error instanceof Error)200})201 202test('FST_ERR_DEC_ALREADY_PRESENT', t => {203 t.plan(5)204 const error = new errors.FST_ERR_DEC_ALREADY_PRESENT()205 t.assert.strictEqual(error.name, 'FastifyError')206 t.assert.strictEqual(error.code, 'FST_ERR_DEC_ALREADY_PRESENT')207 t.assert.strictEqual(error.message, "The decorator '%s' has already been added!")208 t.assert.strictEqual(error.statusCode, 500)209 t.assert.ok(error instanceof Error)210})211 212test('FST_ERR_DEC_DEPENDENCY_INVALID_TYPE', t => {213 t.plan(5)214 const error = new errors.FST_ERR_DEC_DEPENDENCY_INVALID_TYPE()215 t.assert.strictEqual(error.name, 'FastifyError')216 t.assert.strictEqual(error.code, 'FST_ERR_DEC_DEPENDENCY_INVALID_TYPE')217 t.assert.strictEqual(error.message, "The dependencies of decorator '%s' must be of type Array.")218 t.assert.strictEqual(error.statusCode, 500)219 t.assert.ok(error instanceof TypeError)220})221 222test('FST_ERR_DEC_MISSING_DEPENDENCY', t => {223 t.plan(5)224 const error = new errors.FST_ERR_DEC_MISSING_DEPENDENCY()225 t.assert.strictEqual(error.name, 'FastifyError')226 t.assert.strictEqual(error.code, 'FST_ERR_DEC_MISSING_DEPENDENCY')227 t.assert.strictEqual(error.message, "The decorator is missing dependency '%s'.")228 t.assert.strictEqual(error.statusCode, 500)229 t.assert.ok(error instanceof Error)230})231 232test('FST_ERR_DEC_AFTER_START', t => {233 t.plan(5)234 const error = new errors.FST_ERR_DEC_AFTER_START()235 t.assert.strictEqual(error.name, 'FastifyError')236 t.assert.strictEqual(error.code, 'FST_ERR_DEC_AFTER_START')237 t.assert.strictEqual(error.message, "The decorator '%s' has been added after start!")238 t.assert.strictEqual(error.statusCode, 500)239 t.assert.ok(error instanceof Error)240})241 242test('FST_ERR_DEC_REFERENCE_TYPE', t => {243 t.plan(5)244 const error = new errors.FST_ERR_DEC_REFERENCE_TYPE()245 t.assert.strictEqual(error.name, 'FastifyError')246 t.assert.strictEqual(error.code, 'FST_ERR_DEC_REFERENCE_TYPE')247 t.assert.strictEqual(error.message, "The decorator '%s' of type '%s' is a reference type. Use the { getter, setter } interface instead.")248 t.assert.strictEqual(error.statusCode, 500)249 t.assert.ok(error instanceof Error)250})251 252test('FST_ERR_HOOK_INVALID_TYPE', t => {253 t.plan(5)254 const error = new errors.FST_ERR_HOOK_INVALID_TYPE()255 t.assert.strictEqual(error.name, 'FastifyError')256 t.assert.strictEqual(error.code, 'FST_ERR_HOOK_INVALID_TYPE')257 t.assert.strictEqual(error.message, 'The hook name must be a string')258 t.assert.strictEqual(error.statusCode, 500)259 t.assert.ok(error instanceof TypeError)260})261 262test('FST_ERR_HOOK_INVALID_HANDLER', t => {263 t.plan(5)264 const error = new errors.FST_ERR_HOOK_INVALID_HANDLER()265 t.assert.strictEqual(error.name, 'FastifyError')266 t.assert.strictEqual(error.code, 'FST_ERR_HOOK_INVALID_HANDLER')267 t.assert.strictEqual(error.message, '%s hook should be a function, instead got %s')268 t.assert.strictEqual(error.statusCode, 500)269 t.assert.ok(error instanceof TypeError)270})271 272test('FST_ERR_HOOK_INVALID_ASYNC_HANDLER', t => {273 t.plan(5)274 const error = new errors.FST_ERR_HOOK_INVALID_ASYNC_HANDLER()275 t.assert.strictEqual(error.name, 'FastifyError')276 t.assert.strictEqual(error.code, 'FST_ERR_HOOK_INVALID_ASYNC_HANDLER')277 t.assert.strictEqual(error.message, "Async function has too many arguments. Async hooks should not use the 'done' argument.")278 t.assert.strictEqual(error.statusCode, 500)279 t.assert.ok(error instanceof TypeError)280})281 282test('FST_ERR_HOOK_NOT_SUPPORTED', t => {283 t.plan(5)284 const error = new errors.FST_ERR_HOOK_NOT_SUPPORTED()285 t.assert.strictEqual(error.name, 'FastifyError')286 t.assert.strictEqual(error.code, 'FST_ERR_HOOK_NOT_SUPPORTED')287 t.assert.strictEqual(error.message, '%s hook not supported!')288 t.assert.strictEqual(error.statusCode, 500)289 t.assert.ok(error instanceof TypeError)290})291 292test('FST_ERR_MISSING_MIDDLEWARE', t => {293 t.plan(5)294 const error = new errors.FST_ERR_MISSING_MIDDLEWARE()295 t.assert.strictEqual(error.name, 'FastifyError')296 t.assert.strictEqual(error.code, 'FST_ERR_MISSING_MIDDLEWARE')297 t.assert.strictEqual(error.message, 'You must register a plugin for handling middlewares, visit fastify.dev/docs/latest/Reference/Middleware/ for more info.')298 t.assert.strictEqual(error.statusCode, 500)299 t.assert.ok(error instanceof Error)300})301 302test('FST_ERR_HOOK_TIMEOUT', t => {303 t.plan(5)304 const error = new errors.FST_ERR_HOOK_TIMEOUT()305 t.assert.strictEqual(error.name, 'FastifyError')306 t.assert.strictEqual(error.code, 'FST_ERR_HOOK_TIMEOUT')307 t.assert.strictEqual(error.message, "A callback for '%s' hook%s timed out. You may have forgotten to call 'done' function or to resolve a Promise")308 t.assert.strictEqual(error.statusCode, 500)309 t.assert.ok(error instanceof Error)310})311 312test('FST_ERR_LOG_INVALID_DESTINATION', t => {313 t.plan(5)314 const error = new errors.FST_ERR_LOG_INVALID_DESTINATION()315 t.assert.strictEqual(error.name, 'FastifyError')316 t.assert.strictEqual(error.code, 'FST_ERR_LOG_INVALID_DESTINATION')317 t.assert.strictEqual(error.message, 'Cannot specify both logger.stream and logger.file options')318 t.assert.strictEqual(error.statusCode, 500)319 t.assert.ok(error instanceof Error)320})321 322test('FST_ERR_LOG_INVALID_LOGGER', t => {323 t.plan(5)324 const error = new errors.FST_ERR_LOG_INVALID_LOGGER()325 t.assert.strictEqual(error.name, 'FastifyError')326 t.assert.strictEqual(error.code, 'FST_ERR_LOG_INVALID_LOGGER')327 t.assert.strictEqual(error.message, "Invalid logger object provided. The logger instance should have these functions(s): '%s'.")328 t.assert.strictEqual(error.statusCode, 500)329 t.assert.ok(error instanceof TypeError)330})331 332test('FST_ERR_LOG_INVALID_LOGGER_INSTANCE', t => {333 t.plan(5)334 const error = new errors.FST_ERR_LOG_INVALID_LOGGER_INSTANCE()335 t.assert.strictEqual(error.name, 'FastifyError')336 t.assert.strictEqual(error.code, 'FST_ERR_LOG_INVALID_LOGGER_INSTANCE')337 t.assert.strictEqual(error.message, 'loggerInstance only accepts a logger instance.')338 t.assert.strictEqual(error.statusCode, 500)339 t.assert.ok(error instanceof TypeError)340})341 342test('FST_ERR_LOG_INVALID_LOGGER_CONFIG', t => {343 t.plan(5)344 const error = new errors.FST_ERR_LOG_INVALID_LOGGER_CONFIG()345 t.assert.strictEqual(error.name, 'FastifyError')346 t.assert.strictEqual(error.code, 'FST_ERR_LOG_INVALID_LOGGER_CONFIG')347 t.assert.strictEqual(error.message, 'logger options only accepts a configuration object.')348 t.assert.strictEqual(error.statusCode, 500)349 t.assert.ok(error instanceof TypeError)350})351 352test('FST_ERR_LOG_LOGGER_AND_LOGGER_INSTANCE_PROVIDED', t => {353 t.plan(5)354 const error = new errors.FST_ERR_LOG_LOGGER_AND_LOGGER_INSTANCE_PROVIDED()355 t.assert.strictEqual(error.name, 'FastifyError')356 t.assert.strictEqual(error.code, 'FST_ERR_LOG_LOGGER_AND_LOGGER_INSTANCE_PROVIDED')357 t.assert.strictEqual(error.message, 'You cannot provide both logger and loggerInstance. Please provide only one.')358 t.assert.strictEqual(error.statusCode, 500)359 t.assert.ok(error instanceof TypeError)360})361 362test('FST_ERR_REP_INVALID_PAYLOAD_TYPE', t => {363 t.plan(5)364 const error = new errors.FST_ERR_REP_INVALID_PAYLOAD_TYPE()365 t.assert.strictEqual(error.name, 'FastifyError')366 t.assert.strictEqual(error.code, 'FST_ERR_REP_INVALID_PAYLOAD_TYPE')367 t.assert.strictEqual(error.message, "Attempted to send payload of invalid type '%s'. Expected a string or Buffer.")368 t.assert.strictEqual(error.statusCode, 500)369 t.assert.ok(error instanceof TypeError)370})371 372test('FST_ERR_REP_RESPONSE_BODY_CONSUMED', t => {373 t.plan(5)374 const error = new errors.FST_ERR_REP_RESPONSE_BODY_CONSUMED()375 t.assert.strictEqual(error.name, 'FastifyError')376 t.assert.strictEqual(error.code, 'FST_ERR_REP_RESPONSE_BODY_CONSUMED')377 t.assert.strictEqual(error.message, 'Response.body is already consumed.')378 t.assert.strictEqual(error.statusCode, 500)379 t.assert.ok(error instanceof Error)380})381 382test('FST_ERR_REP_READABLE_STREAM_LOCKED', t => {383 t.plan(5)384 const error = new errors.FST_ERR_REP_READABLE_STREAM_LOCKED()385 t.assert.strictEqual(error.name, 'FastifyError')386 t.assert.strictEqual(error.code, 'FST_ERR_REP_READABLE_STREAM_LOCKED')387 t.assert.strictEqual(error.message, 'ReadableStream was locked. You should call releaseLock() method on reader before sending.')388 t.assert.strictEqual(error.statusCode, 500)389 t.assert.ok(error instanceof Error)390})391 392test('FST_ERR_REP_ALREADY_SENT', t => {393 t.plan(5)394 const error = new errors.FST_ERR_REP_ALREADY_SENT('/hello', 'GET')395 t.assert.strictEqual(error.name, 'FastifyError')396 t.assert.strictEqual(error.code, 'FST_ERR_REP_ALREADY_SENT')397 t.assert.strictEqual(error.message, 'Reply was already sent, did you forget to "return reply" in "/hello" (GET)?')398 t.assert.strictEqual(error.statusCode, 500)399 t.assert.ok(error instanceof Error)400})401 402test('FST_ERR_REP_SENT_VALUE', t => {403 t.plan(5)404 const error = new errors.FST_ERR_REP_SENT_VALUE()405 t.assert.strictEqual(error.name, 'FastifyError')406 t.assert.strictEqual(error.code, 'FST_ERR_REP_SENT_VALUE')407 t.assert.strictEqual(error.message, 'The only possible value for reply.sent is true.')408 t.assert.strictEqual(error.statusCode, 500)409 t.assert.ok(error instanceof TypeError)410})411 412test('FST_ERR_SEND_INSIDE_ONERR', t => {413 t.plan(5)414 const error = new errors.FST_ERR_SEND_INSIDE_ONERR()415 t.assert.strictEqual(error.name, 'FastifyError')416 t.assert.strictEqual(error.code, 'FST_ERR_SEND_INSIDE_ONERR')417 t.assert.strictEqual(error.message, 'You cannot use `send` inside the `onError` hook')418 t.assert.strictEqual(error.statusCode, 500)419 t.assert.ok(error instanceof Error)420})421 422test('FST_ERR_SEND_UNDEFINED_ERR', t => {423 t.plan(5)424 const error = new errors.FST_ERR_SEND_UNDEFINED_ERR()425 t.assert.strictEqual(error.name, 'FastifyError')426 t.assert.strictEqual(error.code, 'FST_ERR_SEND_UNDEFINED_ERR')427 t.assert.strictEqual(error.message, 'Undefined error has occurred')428 t.assert.strictEqual(error.statusCode, 500)429 t.assert.ok(error instanceof Error)430})431 432test('FST_ERR_BAD_STATUS_CODE', t => {433 t.plan(5)434 const error = new errors.FST_ERR_BAD_STATUS_CODE()435 t.assert.strictEqual(error.name, 'FastifyError')436 t.assert.strictEqual(error.code, 'FST_ERR_BAD_STATUS_CODE')437 t.assert.strictEqual(error.message, 'Called reply with an invalid status code: %s')438 t.assert.strictEqual(error.statusCode, 500)439 t.assert.ok(error instanceof Error)440})441 442test('FST_ERR_BAD_TRAILER_NAME', t => {443 t.plan(5)444 const error = new errors.FST_ERR_BAD_TRAILER_NAME()445 t.assert.strictEqual(error.name, 'FastifyError')446 t.assert.strictEqual(error.code, 'FST_ERR_BAD_TRAILER_NAME')447 t.assert.strictEqual(error.message, 'Called reply.trailer with an invalid header name: %s')448 t.assert.strictEqual(error.statusCode, 500)449 t.assert.ok(error instanceof Error)450})451 452test('FST_ERR_BAD_TRAILER_VALUE', t => {453 t.plan(5)454 const error = new errors.FST_ERR_BAD_TRAILER_VALUE()455 t.assert.strictEqual(error.name, 'FastifyError')456 t.assert.strictEqual(error.code, 'FST_ERR_BAD_TRAILER_VALUE')457 t.assert.strictEqual(error.message, "Called reply.trailer('%s', fn) with an invalid type: %s. Expected a function.")458 t.assert.strictEqual(error.statusCode, 500)459 t.assert.ok(error instanceof Error)460})461 462test('FST_ERR_FAILED_ERROR_SERIALIZATION', t => {463 t.plan(5)464 const error = new errors.FST_ERR_FAILED_ERROR_SERIALIZATION()465 t.assert.strictEqual(error.name, 'FastifyError')466 t.assert.strictEqual(error.code, 'FST_ERR_FAILED_ERROR_SERIALIZATION')467 t.assert.strictEqual(error.message, 'Failed to serialize an error. Error: %s. Original error: %s')468 t.assert.strictEqual(error.statusCode, 500)469 t.assert.ok(error instanceof Error)470})471 472test('FST_ERR_MISSING_SERIALIZATION_FN', t => {473 t.plan(5)474 const error = new errors.FST_ERR_MISSING_SERIALIZATION_FN()475 t.assert.strictEqual(error.name, 'FastifyError')476 t.assert.strictEqual(error.code, 'FST_ERR_MISSING_SERIALIZATION_FN')477 t.assert.strictEqual(error.message, 'Missing serialization function. Key "%s"')478 t.assert.strictEqual(error.statusCode, 500)479 t.assert.ok(error instanceof Error)480})481 482test('FST_ERR_MISSING_CONTENTTYPE_SERIALIZATION_FN', t => {483 t.plan(5)484 const error = new errors.FST_ERR_MISSING_CONTENTTYPE_SERIALIZATION_FN()485 t.assert.strictEqual(error.name, 'FastifyError')486 t.assert.strictEqual(error.code, 'FST_ERR_MISSING_CONTENTTYPE_SERIALIZATION_FN')487 t.assert.strictEqual(error.message, 'Missing serialization function. Key "%s:%s"')488 t.assert.strictEqual(error.statusCode, 500)489 t.assert.ok(error instanceof Error)490})491 492test('FST_ERR_REQ_INVALID_VALIDATION_INVOCATION', t => {493 t.plan(5)494 const error = new errors.FST_ERR_REQ_INVALID_VALIDATION_INVOCATION()495 t.assert.strictEqual(error.name, 'FastifyError')496 t.assert.strictEqual(error.code, 'FST_ERR_REQ_INVALID_VALIDATION_INVOCATION')497 t.assert.strictEqual(error.message, 'Invalid validation invocation. Missing validation function for HTTP part "%s" nor schema provided.')498 t.assert.strictEqual(error.statusCode, 500)499 t.assert.ok(error instanceof Error)500})501 502test('FST_ERR_SCH_MISSING_ID', t => {503 t.plan(5)504 const error = new errors.FST_ERR_SCH_MISSING_ID()505 t.assert.strictEqual(error.name, 'FastifyError')506 t.assert.strictEqual(error.code, 'FST_ERR_SCH_MISSING_ID')507 t.assert.strictEqual(error.message, 'Missing schema $id property')508 t.assert.strictEqual(error.statusCode, 500)509 t.assert.ok(error instanceof Error)510})511 512test('FST_ERR_SCH_ALREADY_PRESENT', t => {513 t.plan(5)514 const error = new errors.FST_ERR_SCH_ALREADY_PRESENT()515 t.assert.strictEqual(error.name, 'FastifyError')516 t.assert.strictEqual(error.code, 'FST_ERR_SCH_ALREADY_PRESENT')517 t.assert.strictEqual(error.message, "Schema with id '%s' already declared!")518 t.assert.strictEqual(error.statusCode, 500)519 t.assert.ok(error instanceof Error)520})521 522test('FST_ERR_SCH_CONTENT_MISSING_SCHEMA', t => {523 t.plan(5)524 const error = new errors.FST_ERR_SCH_CONTENT_MISSING_SCHEMA()525 t.assert.strictEqual(error.name, 'FastifyError')526 t.assert.strictEqual(error.code, 'FST_ERR_SCH_CONTENT_MISSING_SCHEMA')527 t.assert.strictEqual(error.message, "Schema is missing for the content type '%s'")528 t.assert.strictEqual(error.statusCode, 500)529 t.assert.ok(error instanceof Error)530})531 532test('FST_ERR_SCH_DUPLICATE', t => {533 t.plan(5)534 const error = new errors.FST_ERR_SCH_DUPLICATE()535 t.assert.strictEqual(error.name, 'FastifyError')536 t.assert.strictEqual(error.code, 'FST_ERR_SCH_DUPLICATE')537 t.assert.strictEqual(error.message, "Schema with '%s' already present!")538 t.assert.strictEqual(error.statusCode, 500)539 t.assert.ok(error instanceof Error)540})541 542test('FST_ERR_SCH_VALIDATION_BUILD', t => {543 t.plan(5)544 const error = new errors.FST_ERR_SCH_VALIDATION_BUILD()545 t.assert.strictEqual(error.name, 'FastifyError')546 t.assert.strictEqual(error.code, 'FST_ERR_SCH_VALIDATION_BUILD')547 t.assert.strictEqual(error.message, 'Failed building the validation schema for %s: %s, due to error %s')548 t.assert.strictEqual(error.statusCode, 500)549 t.assert.ok(error instanceof Error)550})551 552test('FST_ERR_SCH_SERIALIZATION_BUILD', t => {553 t.plan(5)554 const error = new errors.FST_ERR_SCH_SERIALIZATION_BUILD()555 t.assert.strictEqual(error.name, 'FastifyError')556 t.assert.strictEqual(error.code, 'FST_ERR_SCH_SERIALIZATION_BUILD')557 t.assert.strictEqual(error.message, 'Failed building the serialization schema for %s: %s, due to error %s')558 t.assert.strictEqual(error.statusCode, 500)559 t.assert.ok(error instanceof Error)560})561 562test('FST_ERR_SCH_RESPONSE_SCHEMA_NOT_NESTED_2XX', t => {563 t.plan(5)564 const error = new errors.FST_ERR_SCH_RESPONSE_SCHEMA_NOT_NESTED_2XX()565 t.assert.strictEqual(error.name, 'FastifyError')566 t.assert.strictEqual(error.code, 'FST_ERR_SCH_RESPONSE_SCHEMA_NOT_NESTED_2XX')567 t.assert.strictEqual(error.message, 'response schemas should be nested under a valid status code, e.g { 2xx: { type: "object" } }')568 t.assert.strictEqual(error.statusCode, 500)569 t.assert.ok(error instanceof Error)570})571 572test('FST_ERR_HTTP2_INVALID_VERSION', t => {573 t.plan(5)574 const error = new errors.FST_ERR_HTTP2_INVALID_VERSION()575 t.assert.strictEqual(error.name, 'FastifyError')576 t.assert.strictEqual(error.code, 'FST_ERR_HTTP2_INVALID_VERSION')577 t.assert.strictEqual(error.message, 'HTTP2 is available only from node >= 8.8.1')578 t.assert.strictEqual(error.statusCode, 500)579 t.assert.ok(error instanceof Error)580})581 582test('FST_ERR_INIT_OPTS_INVALID', t => {583 t.plan(5)584 const error = new errors.FST_ERR_INIT_OPTS_INVALID()585 t.assert.strictEqual(error.name, 'FastifyError')586 t.assert.strictEqual(error.code, 'FST_ERR_INIT_OPTS_INVALID')587 t.assert.strictEqual(error.message, "Invalid initialization options: '%s'")588 t.assert.strictEqual(error.statusCode, 500)589 t.assert.ok(error instanceof Error)590})591 592test('FST_ERR_FORCE_CLOSE_CONNECTIONS_IDLE_NOT_AVAILABLE', t => {593 t.plan(5)594 const error = new errors.FST_ERR_FORCE_CLOSE_CONNECTIONS_IDLE_NOT_AVAILABLE()595 t.assert.strictEqual(error.name, 'FastifyError')596 t.assert.strictEqual(error.code, 'FST_ERR_FORCE_CLOSE_CONNECTIONS_IDLE_NOT_AVAILABLE')597 t.assert.strictEqual(error.message, "Cannot set forceCloseConnections to 'idle' as your HTTP server does not support closeIdleConnections method")598 t.assert.strictEqual(error.statusCode, 500)599 t.assert.ok(error instanceof Error)600})601 602test('FST_ERR_DUPLICATED_ROUTE', t => {603 t.plan(5)604 const error = new errors.FST_ERR_DUPLICATED_ROUTE()605 t.assert.strictEqual(error.name, 'FastifyError')606 t.assert.strictEqual(error.code, 'FST_ERR_DUPLICATED_ROUTE')607 t.assert.strictEqual(error.message, "Method '%s' already declared for route '%s'")608 t.assert.strictEqual(error.statusCode, 500)609 t.assert.ok(error instanceof Error)610})611 612test('FST_ERR_BAD_URL', t => {613 t.plan(5)614 const error = new errors.FST_ERR_BAD_URL()615 t.assert.strictEqual(error.name, 'FastifyError')616 t.assert.strictEqual(error.code, 'FST_ERR_BAD_URL')617 t.assert.strictEqual(error.message, "'%s' is not a valid url component")618 t.assert.strictEqual(error.statusCode, 400)619 t.assert.ok(error instanceof Error)620})621 622test('FST_ERR_ASYNC_CONSTRAINT', t => {623 t.plan(5)624 const error = new errors.FST_ERR_ASYNC_CONSTRAINT()625 t.assert.strictEqual(error.name, 'FastifyError')626 t.assert.strictEqual(error.code, 'FST_ERR_ASYNC_CONSTRAINT')627 t.assert.strictEqual(error.message, 'Unexpected error from async constraint')628 t.assert.strictEqual(error.statusCode, 500)629 t.assert.ok(error instanceof Error)630})631 632test('FST_ERR_INVALID_URL', t => {633 t.plan(5)634 const error = new errors.FST_ERR_INVALID_URL()635 t.assert.strictEqual(error.name, 'FastifyError')636 t.assert.strictEqual(error.code, 'FST_ERR_INVALID_URL')637 t.assert.strictEqual(error.message, "URL must be a string. Received '%s'")638 t.assert.strictEqual(error.statusCode, 400)639 t.assert.ok(error instanceof TypeError)640})641 642test('FST_ERR_ROUTE_OPTIONS_NOT_OBJ', t => {643 t.plan(5)644 const error = new errors.FST_ERR_ROUTE_OPTIONS_NOT_OBJ()645 t.assert.strictEqual(error.name, 'FastifyError')646 t.assert.strictEqual(error.code, 'FST_ERR_ROUTE_OPTIONS_NOT_OBJ')647 t.assert.strictEqual(error.message, 'Options for "%s:%s" route must be an object')648 t.assert.strictEqual(error.statusCode, 500)649 t.assert.ok(error instanceof TypeError)650})651 652test('FST_ERR_ROUTE_DUPLICATED_HANDLER', t => {653 t.plan(5)654 const error = new errors.FST_ERR_ROUTE_DUPLICATED_HANDLER()655 t.assert.strictEqual(error.name, 'FastifyError')656 t.assert.strictEqual(error.code, 'FST_ERR_ROUTE_DUPLICATED_HANDLER')657 t.assert.strictEqual(error.message, 'Duplicate handler for "%s:%s" route is not allowed!')658 t.assert.strictEqual(error.statusCode, 500)659 t.assert.ok(error instanceof Error)660})661 662test('FST_ERR_ROUTE_HANDLER_NOT_FN', t => {663 t.plan(5)664 const error = new errors.FST_ERR_ROUTE_HANDLER_NOT_FN()665 t.assert.strictEqual(error.name, 'FastifyError')666 t.assert.strictEqual(error.code, 'FST_ERR_ROUTE_HANDLER_NOT_FN')667 t.assert.strictEqual(error.message, 'Error Handler for %s:%s route, if defined, must be a function')668 t.assert.strictEqual(error.statusCode, 500)669 t.assert.ok(error instanceof TypeError)670})671 672test('FST_ERR_ROUTE_MISSING_HANDLER', t => {673 t.plan(5)674 const error = new errors.FST_ERR_ROUTE_MISSING_HANDLER()675 t.assert.strictEqual(error.name, 'FastifyError')676 t.assert.strictEqual(error.code, 'FST_ERR_ROUTE_MISSING_HANDLER')677 t.assert.strictEqual(error.message, 'Missing handler function for "%s:%s" route.')678 t.assert.strictEqual(error.statusCode, 500)679 t.assert.ok(error instanceof Error)680})681 682test('FST_ERR_ROUTE_METHOD_INVALID', t => {683 t.plan(5)684 const error = new errors.FST_ERR_ROUTE_METHOD_INVALID()685 t.assert.strictEqual(error.name, 'FastifyError')686 t.assert.strictEqual(error.code, 'FST_ERR_ROUTE_METHOD_INVALID')687 t.assert.strictEqual(error.message, 'Provided method is invalid!')688 t.assert.strictEqual(error.statusCode, 500)689 t.assert.ok(error instanceof TypeError)690})691 692test('FST_ERR_ROUTE_METHOD_NOT_SUPPORTED', t => {693 t.plan(5)694 const error = new errors.FST_ERR_ROUTE_METHOD_NOT_SUPPORTED()695 t.assert.strictEqual(error.name, 'FastifyError')696 t.assert.strictEqual(error.code, 'FST_ERR_ROUTE_METHOD_NOT_SUPPORTED')697 t.assert.strictEqual(error.message, '%s method is not supported.')698 t.assert.strictEqual(error.statusCode, 500)699 t.assert.ok(error instanceof Error)700})701 702test('FST_ERR_ROUTE_BODY_VALIDATION_SCHEMA_NOT_SUPPORTED', t => {703 t.plan(5)704 const error = new errors.FST_ERR_ROUTE_BODY_VALIDATION_SCHEMA_NOT_SUPPORTED()705 t.assert.strictEqual(error.name, 'FastifyError')706 t.assert.strictEqual(error.code, 'FST_ERR_ROUTE_BODY_VALIDATION_SCHEMA_NOT_SUPPORTED')707 t.assert.strictEqual(error.message, 'Body validation schema for %s:%s route is not supported!')708 t.assert.strictEqual(error.statusCode, 500)709 t.assert.ok(error instanceof Error)710})711 712test('FST_ERR_ROUTE_BODY_LIMIT_OPTION_NOT_INT', t => {713 t.plan(5)714 const error = new errors.FST_ERR_ROUTE_BODY_LIMIT_OPTION_NOT_INT()715 t.assert.strictEqual(error.name, 'FastifyError')716 t.assert.strictEqual(error.code, 'FST_ERR_ROUTE_BODY_LIMIT_OPTION_NOT_INT')717 t.assert.strictEqual(error.message, "'bodyLimit' option must be an integer > 0. Got '%s'")718 t.assert.strictEqual(error.statusCode, 500)719 t.assert.ok(error instanceof TypeError)720})721 722test('FST_ERR_ROUTE_BODY_LIMIT_OPTION_NOT_INT', t => {723 t.plan(5)724 const error = new errors.FST_ERR_ROUTE_BODY_LIMIT_OPTION_NOT_INT()725 t.assert.strictEqual(error.name, 'FastifyError')726 t.assert.strictEqual(error.code, 'FST_ERR_ROUTE_BODY_LIMIT_OPTION_NOT_INT')727 t.assert.strictEqual(error.message, "'bodyLimit' option must be an integer > 0. Got '%s'")728 t.assert.strictEqual(error.statusCode, 500)729 t.assert.ok(error instanceof TypeError)730})731 732test('FST_ERR_ROUTE_REWRITE_NOT_STR', t => {733 t.plan(5)734 const error = new errors.FST_ERR_ROUTE_REWRITE_NOT_STR()735 t.assert.strictEqual(error.name, 'FastifyError')736 t.assert.strictEqual(error.code, 'FST_ERR_ROUTE_REWRITE_NOT_STR')737 t.assert.strictEqual(error.message, 'Rewrite url for "%s" needs to be of type "string" but received "%s"')738 t.assert.strictEqual(error.statusCode, 500)739 t.assert.ok(error instanceof TypeError)740})741 742test('FST_ERR_REOPENED_CLOSE_SERVER', t => {743 t.plan(5)744 const error = new errors.FST_ERR_REOPENED_CLOSE_SERVER()745 t.assert.strictEqual(error.name, 'FastifyError')746 t.assert.strictEqual(error.code, 'FST_ERR_REOPENED_CLOSE_SERVER')747 t.assert.strictEqual(error.message, 'Fastify has already been closed and cannot be reopened')748 t.assert.strictEqual(error.statusCode, 500)749 t.assert.ok(error instanceof Error)750})751 752test('FST_ERR_REOPENED_SERVER', t => {753 t.plan(5)754 const error = new errors.FST_ERR_REOPENED_SERVER()755 t.assert.strictEqual(error.name, 'FastifyError')756 t.assert.strictEqual(error.code, 'FST_ERR_REOPENED_SERVER')757 t.assert.strictEqual(error.message, 'Fastify is already listening')758 t.assert.strictEqual(error.statusCode, 500)759 t.assert.ok(error instanceof Error)760})761 762test('FST_ERR_INSTANCE_ALREADY_LISTENING', t => {763 t.plan(5)764 const error = new errors.FST_ERR_INSTANCE_ALREADY_LISTENING()765 t.assert.strictEqual(error.name, 'FastifyError')766 t.assert.strictEqual(error.code, 'FST_ERR_INSTANCE_ALREADY_LISTENING')767 t.assert.strictEqual(error.message, 'Fastify instance is already listening. %s')768 t.assert.strictEqual(error.statusCode, 500)769 t.assert.ok(error instanceof Error)770})771 772test('FST_ERR_PLUGIN_VERSION_MISMATCH', t => {773 t.plan(5)774 const error = new errors.FST_ERR_PLUGIN_VERSION_MISMATCH()775 t.assert.strictEqual(error.name, 'FastifyError')776 t.assert.strictEqual(error.code, 'FST_ERR_PLUGIN_VERSION_MISMATCH')777 t.assert.strictEqual(error.message, "fastify-plugin: %s - expected '%s' fastify version, '%s' is installed")778 t.assert.strictEqual(error.statusCode, 500)779 t.assert.ok(error instanceof Error)780})781 782test('FST_ERR_PLUGIN_NOT_PRESENT_IN_INSTANCE', t => {783 t.plan(5)784 const error = new errors.FST_ERR_PLUGIN_NOT_PRESENT_IN_INSTANCE()785 t.assert.strictEqual(error.name, 'FastifyError')786 t.assert.strictEqual(error.code, 'FST_ERR_PLUGIN_NOT_PRESENT_IN_INSTANCE')787 t.assert.strictEqual(error.message, "The decorator '%s'%s is not present in %s")788 t.assert.strictEqual(error.statusCode, 500)789 t.assert.ok(error instanceof Error)790})791 792test('FST_ERR_PLUGIN_INVALID_ASYNC_HANDLER', t => {793 t.plan(5)794 const error = new errors.FST_ERR_PLUGIN_INVALID_ASYNC_HANDLER('easter-egg')795 t.assert.strictEqual(error.name, 'FastifyError')796 t.assert.strictEqual(error.code, 'FST_ERR_PLUGIN_INVALID_ASYNC_HANDLER')797 t.assert.strictEqual(error.message, 'The easter-egg plugin being registered mixes async and callback styles. Async plugin should not mix async and callback style.')798 t.assert.strictEqual(error.statusCode, 500)799 t.assert.ok(error instanceof TypeError)800})801 802test('FST_ERR_PLUGIN_CALLBACK_NOT_FN', t => {803 t.plan(5)804 const error = new errors.FST_ERR_PLUGIN_CALLBACK_NOT_FN()805 t.assert.strictEqual(error.name, 'FastifyError')806 t.assert.strictEqual(error.code, 'FST_ERR_PLUGIN_CALLBACK_NOT_FN')807 t.assert.strictEqual(error.message, 'fastify-plugin: %s')808 t.assert.strictEqual(error.statusCode, 500)809 t.assert.ok(error instanceof TypeError)810})811 812test('FST_ERR_PLUGIN_NOT_VALID', t => {813 t.plan(5)814 const error = new errors.FST_ERR_PLUGIN_NOT_VALID()815 t.assert.strictEqual(error.name, 'FastifyError')816 t.assert.strictEqual(error.code, 'FST_ERR_PLUGIN_NOT_VALID')817 t.assert.strictEqual(error.message, 'fastify-plugin: %s')818 t.assert.strictEqual(error.statusCode, 500)819 t.assert.ok(error instanceof Error)820})821 822test('FST_ERR_ROOT_PLG_BOOTED', t => {823 t.plan(5)824 const error = new errors.FST_ERR_ROOT_PLG_BOOTED()825 t.assert.strictEqual(error.name, 'FastifyError')826 t.assert.strictEqual(error.code, 'FST_ERR_ROOT_PLG_BOOTED')827 t.assert.strictEqual(error.message, 'fastify-plugin: %s')828 t.assert.strictEqual(error.statusCode, 500)829 t.assert.ok(error instanceof Error)830})831 832test('FST_ERR_PARENT_PLUGIN_BOOTED', t => {833 t.plan(5)834 const error = new errors.FST_ERR_PARENT_PLUGIN_BOOTED()835 t.assert.strictEqual(error.name, 'FastifyError')836 t.assert.strictEqual(error.code, 'FST_ERR_PARENT_PLUGIN_BOOTED')837 t.assert.strictEqual(error.message, 'fastify-plugin: %s')838 t.assert.strictEqual(error.statusCode, 500)839 t.assert.ok(error instanceof Error)840})841 842test('FST_ERR_PLUGIN_TIMEOUT', t => {843 t.plan(5)844 const error = new errors.FST_ERR_PLUGIN_TIMEOUT()845 t.assert.strictEqual(error.name, 'FastifyError')846 t.assert.strictEqual(error.code, 'FST_ERR_PLUGIN_TIMEOUT')847 t.assert.strictEqual(error.message, 'fastify-plugin: %s')848 t.assert.strictEqual(error.statusCode, 500)849 t.assert.ok(error instanceof Error)850})851 852test('FST_ERR_VALIDATION', t => {853 t.plan(5)854 const error = new errors.FST_ERR_VALIDATION()855 t.assert.strictEqual(error.name, 'FastifyError')856 t.assert.strictEqual(error.code, 'FST_ERR_VALIDATION')857 t.assert.strictEqual(error.message, '%s')858 t.assert.strictEqual(error.statusCode, 400)859 t.assert.ok(error instanceof Error)860})861 862test('FST_ERR_LISTEN_OPTIONS_INVALID', t => {863 t.plan(5)864 const error = new errors.FST_ERR_LISTEN_OPTIONS_INVALID()865 t.assert.strictEqual(error.name, 'FastifyError')866 t.assert.strictEqual(error.code, 'FST_ERR_LISTEN_OPTIONS_INVALID')867 t.assert.strictEqual(error.message, "Invalid listen options: '%s'")868 t.assert.strictEqual(error.statusCode, 500)869 t.assert.ok(error instanceof TypeError)870})871 872test('FST_ERR_ERROR_HANDLER_NOT_FN', t => {873 t.plan(5)874 const error = new errors.FST_ERR_ERROR_HANDLER_NOT_FN()875 t.assert.strictEqual(error.name, 'FastifyError')876 t.assert.strictEqual(error.code, 'FST_ERR_ERROR_HANDLER_NOT_FN')877 t.assert.strictEqual(error.message, 'Error Handler must be a function')878 t.assert.strictEqual(error.statusCode, 500)879 t.assert.ok(error instanceof TypeError)880})881 882test('Ensure that all errors are in Errors.md TOC', t => {883 t.plan(expectedErrors)884 const errorsMd = readFileSync(resolve(__dirname, '../../docs/Reference/Errors.md'), 'utf8')885 886 const exportedKeys = Object.keys(errors)887 for (const key of exportedKeys) {888 if (errors[key].name === 'FastifyError') {889 t.assert.ok(errorsMd.includes(` - [${key.toUpperCase()}](#${key.toLowerCase()})`), key)890 }891 }892})893 894test('Ensure that non-existing errors are not in Errors.md TOC', t => {895 t.plan(expectedErrors)896 const errorsMd = readFileSync(resolve(__dirname, '../../docs/Reference/Errors.md'), 'utf8')897 898 const matchRE = / {4}- \[([A-Z0-9_]+)\]\(#[a-z0-9_]+\)/g899 const matches = errorsMd.matchAll(matchRE)900 const exportedKeys = Object.keys(errors)901 902 for (const match of matches) {903 t.assert.ok(exportedKeys.indexOf(match[1]) !== -1, match[1])904 }905})906 907test('Ensure that all errors are in Errors.md documented', t => {908 t.plan(expectedErrors)909 const errorsMd = readFileSync(resolve(__dirname, '../../docs/Reference/Errors.md'), 'utf8')910 911 const exportedKeys = Object.keys(errors)912 for (const key of exportedKeys) {913 if (errors[key].name === 'FastifyError') {914 t.assert.ok(errorsMd.includes(`<a id="${key.toLowerCase()}">${key.toUpperCase()}</a>`), key)915 }916 }917})918 919test('Ensure that non-existing errors are not in Errors.md documented', t => {920 t.plan(expectedErrors)921 const errorsMd = readFileSync(resolve(__dirname, '../../docs/Reference/Errors.md'), 'utf8')922 923 const matchRE = /<a id="[0-9a-zA-Z_]+">([0-9a-zA-Z_]+)<\/a>/g924 const matches = errorsMd.matchAll(matchRE)925 const exportedKeys = Object.keys(errors)926 927 for (const match of matches) {928 t.assert.ok(exportedKeys.indexOf(match[1]) !== -1, match[1])929 }930})931 