{"id":22050129,"url":"https://github.com/icapps/tree-house-errors","last_synced_at":"2025-10-09T16:46:49.353Z","repository":{"id":45033113,"uuid":"123898514","full_name":"icapps/tree-house-errors","owner":"icapps","description":"Errors and error handling","archived":false,"fork":false,"pushed_at":"2023-11-02T10:23:30.000Z","size":1181,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-07-01T08:42:32.426Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/icapps.png","metadata":{"files":{"readme":"README.md","changelog":"HISTORY.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-03-05T09:47:54.000Z","updated_at":"2022-01-13T08:52:35.000Z","dependencies_parsed_at":"2024-09-02T05:01:16.824Z","dependency_job_id":null,"html_url":"https://github.com/icapps/tree-house-errors","commit_stats":{"total_commits":104,"total_committers":5,"mean_commits":20.8,"dds":0.3076923076923077,"last_synced_commit":"01977926888724c6d40aa8e378ef906d295bf407"},"previous_names":[],"tags_count":27,"template":false,"template_full_name":null,"purl":"pkg:github/icapps/tree-house-errors","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/icapps%2Ftree-house-errors","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/icapps%2Ftree-house-errors/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/icapps%2Ftree-house-errors/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/icapps%2Ftree-house-errors/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/icapps","download_url":"https://codeload.github.com/icapps/tree-house-errors/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/icapps%2Ftree-house-errors/sbom","scorecard":{"id":479696,"data":{"date":"2025-08-11","repo":{"name":"github.com/icapps/tree-house-errors","commit":"01977926888724c6d40aa8e378ef906d295bf407"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2,"checks":[{"name":"Code-Review","score":0,"reason":"Found 1/20 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE.md:0","Info: FSF or OSI recognized license: ISC License: LICENSE.md:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 15 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"24 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-968p-4wvh-cqc8","Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92","Warn: Project is vulnerable to: GHSA-c2jc-4fpr-4vhg","Warn: Project is vulnerable to: GHSA-qwcr-r2fm-qrc7","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-pxg6-pf52-xh8x","Warn: Project is vulnerable to: GHSA-h452-7996-h45h","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-rv95-896h-c2vc","Warn: Project is vulnerable to: GHSA-qw6h-vgh9-j6wx","Warn: Project is vulnerable to: GHSA-fjxv-7rqg-78g4","Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-9wv6-86v2-598j","Warn: Project is vulnerable to: GHSA-rhx6-c78j-4q9w","Warn: Project is vulnerable to: GHSA-hrpp-h998-j3pp","Warn: Project is vulnerable to: GHSA-p8p7-x288-28g6","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-m6fv-jmcg-4jfg","Warn: Project is vulnerable to: GHSA-cm22-4g7w-348p","Warn: Project is vulnerable to: GHSA-52f5-9888-hmc6","Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3","Warn: Project is vulnerable to: GHSA-j8xg-fqg3-53r7"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-19T16:17:39.515Z","repository_id":45033113,"created_at":"2025-08-19T16:17:39.515Z","updated_at":"2025-08-19T16:17:39.515Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279001781,"owners_count":26083173,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-09T02:00:07.460Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-30T14:17:58.280Z","updated_at":"2025-10-09T16:46:49.316Z","avatar_url":"https://github.com/icapps.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Treehouse errors\n\nCustom NodeJS error classes and definitions with an error parser utility function\n\n[![npm version](https://badge.fury.io/js/tree-house-errors.svg)](https://badge.fury.io/js/tree-house-errors)\n[![Dependencies](https://david-dm.org/icapps/tree-house-errors.svg)](https://david-dm.org/icapps/tree-house-errors.svg)\n[![Build Status](https://travis-ci.com/icapps/tree-house-errors.svg?branch=master)](https://travis-ci.com/icapps/tree-house-errors)\n[![Coverage Status](https://coveralls.io/repos/github/icapps/tree-house-errors/badge.svg)](https://coveralls.io/github/icapps/tree-house-errors) [![Greenkeeper badge](https://badges.greenkeeper.io/icapps/tree-house-errors.svg)](https://greenkeeper.io/)\n\n## Installation\n\nInstall via npm\n\n```shell\nnpm install @icapps/tree-house-errors\n```\n\nor via yarn\n\n```shell\nyarn add @icapps/tree-house-errors\n```\n\n## Error types\n\n### ApiError\u003cT\u003e\n\nBase error class which extends from the `Error` class.\n`ApiError` accepts a generic `T` for the `details` property; if not specified, it defaults to `any`.\n\n```javascript\n// All keys are required\nconst error = {\n  code: 'BAD_REQUEST_DUE_TO',\n  message: 'This is a bad request',\n}\n\n// All keys are optional\nconst optionalArgs = {\n  message: 'Overwrite the message for custom error',\n  detail: 'Extra details containing pertinent information',\n  stack: 'stacktrace...',\n}\n\nthrow new ApiError(400, error, optionalArgs);\n```\n\n### GenericError\n\nExtends from ApiError with a preset of status code 0 and GENERIC_ERROR as error.\nThis should be used when it's internal without needing an actual status code.\n\n```javascript\nthrow new GenericError(); // or\nthrow new GenericError(error, optionalArgs);\n```\n\n### BadRequestError\n\nExtends from ApiError with a preset of status code 400 and BAD_REQUEST as error.\n\n```javascript\nthrow new BadRequestError(); // or\nthrow new BadRequestError(error, optionalArgs);\n```\n\n### NotFoundError\n\nExtends from ApiError with a preset of status code 404 and RESOURCE_NOT_FOUND as error.\n\n```javascript\nthrow new NotFoundError(); // or\nthrow new NotFoundError(error, optionalArgs);\n```\n\n### ForbiddenError\n\nExtends from ApiError with a preset of status code 403 and FORBIDDEN as error.\n\n```javascript\nthrow new ForbiddenError(); // or\nthrow new ForbiddenError(error, optionalArgs);\n```\n\n### InternalServerError\n\nExtends from ApiError with a preset of status code 500 and INTERNAL_ERROR as error.\n\n```javascript\nthrow new InternalServerError(); // or\nthrow new InternalServerError(error, optionalArgs);\n```\n\n### UnauthorizedError\n\nExtends from ApiError with a preset of status code 401 and UNAUTHORIZED as error.\n\n```javascript\nthrow new UnauthorizedError(); // or\nthrow new UnauthorizedError(error, optionalArgs);\n```\n\n### ValidationError\n\nExtends from ApiError with a preset of status code 400 and INVALID_INPUT as error.\n\n```javascript\nthrow new ValidationError(); // or\nthrow new ValidationError(error, optionalArgs);\n```\n\n### AuthenticationError\n\nExtends from ApiError with a preset of status code 400 and AUTHENTICATION_FAILED as error.\n\n```javascript\nthrow new AuthenticationError(); // or\nthrow new AuthenticationError(error, optionalArgs);\n```\n\n## Error definitions\n\nPredefined error types that can be used over multiple projects with a message and code per type. The current list provides following errors:\n\n```javascript\nINTERNAL_ERROR:         { code: 'INTERNAL_ERROR',i18n: 'internal_error',message: 'An unkown error occurred' },\nINVALID_INPUT:          { code: 'INVALID_INPUT', i18n: 'invalid_input', message: 'Invalid input provided' },\nAUTHENTICATION_FAILED:  { code: 'AUTHENTICATION_FAILED', i18n: 'authentication_failed', message: 'Authentication failed' },\nBAD_REQUEST:            { code: 'BAD_REQUEST', i18n: 'bad_request', message: 'Bad request' },\nMISSING_HEADERS:        { code: 'MISSING_HEADERS', i18n: 'missing_headers', message: 'Missing headers' },\nUNAUTHORIZED:           { code: 'UNAUTHORIZED', i18n: 'unauthorized', message: 'Unauthorized' },\nFORBIDDEN:              { code: 'FORBIDDEN', i18n: 'forbidden', message: 'No access' },\nRESOURCE_NOT_FOUND:     { code: 'RESOURCE_NOT_FOUND', i18n: 'resource_not_found', message: 'Resource not found' },\n```\n\nExample\n\n```javascript\nimport { errorConfig as errors } from '@icapps/tree-house-errors'\nthrow new ApiError(400, errors.BAD_REQUEST);\n```\n\n## Error parsing\n\n### isApiError(apiError, type?)\n\nWill return boolean indicating whether error is instance of `ApiError`.\nCan also be used to provide an extra check matching a specific error type (will only match code, not message)\n\n```javascript\n  // Will return true\n  isApiError(new BadRequestError())\n\n  // Will return false\n  isApiError(new Error('Something'))\n\n  // Will return true\n  isApiError(new BadRequestError(errors.MY_CUSTOM_ERROR), errors.MY_CUSTOM_ERROR)\n```\n\n\u003e Will automatically cast to ApiError if succeeds and using Typescript\n\n### isJsonApiError(object)\n\nWill return boolean indicating whether object has all required properties to be a parsed `ApiError`.\n\n```javascript\n  // Will return true\n  isJsonApiError({ status: 200, code: 'MY_CODE', title: 'MY_ERROR', detail: {} })\n\n  // Will return false\n  isJsonApiError({ status: 200, code: 'MY_CODE' })\n```\n\n\u003e Will automatically cast to ParsedError if succeeds and using Typescript\n\n### parseErrors(error, i18nOptions (optional))\n\nParse any data into an error object with all properties needed for jsonade parser. Also parses [`express-validation`](https://github.com/andrewkeig/express-validation) and [`celebrate`](https://github.com/arb/celebrate) errors.\n\n```javascript\nconst error = new BadRequestError(...);\nconst parsedError = parseErrors(error);\n\n// jsonade serializer afterwards (optional)\nserializer.serialize([parsedError]);\n```\n\nWith i18n support (optional):\n\n```javascript\nconst error = new BadRequestError(...);\nconst parsedError = parseErrors(error, {\n  defaultLocale: 'en',          // Optional (defaults to 'en')\n  language: 'nl',               // Optional (defaults to 'en')\n  path: __dirname = '/locales',\n});\n\n// jsonade serializer afterwards (optional)\nserializer.serialize([parsedError]);\n```\n\n\u003e The `parseErrors` function will load the i18n configuration once, and reuse the same instance afterwards. It is not possible to overwrite the configuration after the first call. This has to do with performance and caching of translations.\n\n### parseJsonErrors(object)\n\nParse json object containing errors into javascript `ApiError` instances. Will return an array with all non-errors filtered out or default InternalServerError if no errors were found.\n\n```javascript\n  try {\n    await doApiCall(...);\n    // Returns { errors: [{ status: 400, code: 'BAD_REQUEST', ... }] }\n  } catch(errorResponse) {\n    const errors = parseJsonResponse(errorResponse);\n    // Will return array containing `ApiError` objects\n  }\n```\n\n\u003e Make sure the object contains an `errors` root key: `{ errors: [ ... ] }`\n\n## Tests\n\n- You can run `npm run test` to run all tests\n- You can run `npm run test:coverage` to run all tests with coverage report\n\n## Bugs\n\nWhen you find issues, please report them:\n\n- web: [https://github.com/icapps/tree-house-errors/issues](https://github.com/icapps/tree-house-errors/issues)\n\nBe sure to include all of the output from the npm command that didn't work as expected. The npm-debug.log file is also helpful to provide.\n\n## Authors\n\nSee the list of [contributors](https://github.com/icapps/tree-house-errors/contributors) who participated in this project.\n\n## License\n\nThis project is licensed under the ISC License - see the [LICENSE.md](LICENSE.md) file for details\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ficapps%2Ftree-house-errors","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ficapps%2Ftree-house-errors","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ficapps%2Ftree-house-errors/lists"}