{"id":13847026,"url":"https://github.com/peerigon/erroz","last_synced_at":"2025-07-12T08:31:13.511Z","repository":{"id":17411250,"uuid":"20184058","full_name":"peerigon/erroz","owner":"peerigon","description":"Streamlined errors with descriptive error messages through metadata and error codes","archived":false,"fork":false,"pushed_at":"2024-09-12T21:21:32.000Z","size":155,"stargazers_count":18,"open_issues_count":3,"forks_count":3,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-06-11T19:39:00.802Z","etag":null,"topics":["error","javascript","jsend","stack-traces","statuscode"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/peerigon.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"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":"2014-05-26T11:32:08.000Z","updated_at":"2024-12-30T22:21:46.000Z","dependencies_parsed_at":"2024-09-13T09:13:13.301Z","dependency_job_id":null,"html_url":"https://github.com/peerigon/erroz","commit_stats":{"total_commits":43,"total_committers":4,"mean_commits":10.75,"dds":0.09302325581395354,"last_synced_commit":"57adf5fa7a86680da2c6460b81aaaceaa57db6bd"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/peerigon/erroz","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peerigon%2Ferroz","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peerigon%2Ferroz/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peerigon%2Ferroz/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peerigon%2Ferroz/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/peerigon","download_url":"https://codeload.github.com/peerigon/erroz/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peerigon%2Ferroz/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264962106,"owners_count":23689738,"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","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":["error","javascript","jsend","stack-traces","statuscode"],"created_at":"2024-08-04T18:00:52.739Z","updated_at":"2025-07-12T08:31:13.258Z","avatar_url":"https://github.com/peerigon.png","language":"TypeScript","readme":"# erroz\n\nDescriptive errors through metadata\n\n[![Build Status](https://travis-ci.org/peerigon/erroz.svg?branch=master)](https://travis-ci.org/peerigon/erroz)\n[![](https://img.shields.io/npm/v/erroz.svg)](https://www.npmjs.com/package/erroz)\n[![](https://img.shields.io/npm/dm/erroz.svg)](https://www.npmjs.com/package/erroz)\n\nTypical strategies of parsing errors are fragile and couple code to the error\nmessages. By defining error objects consistently, working with errors becomes\npredictable and efficient.\n\n## Features\n\n- arbitrary error metadata\n- templated error messages\n- stack traces\n- [JSend](http://labs.omniti.com/labs/jsend) format errors\n\n## Example\n\n```javascript\nimport { erroz } from \"erroz\";\n\nconst DuplicateError = erroz({\n  name: \"Duplicate\",\n  code: \"duplicate\",\n  statusCode: 409,\n  template: \"Resource %resource (%id) already exists\",\n});\n\n// ...\n\nthrow new DuplicateError({ resource: \"Unicorn\", id: 1 });\n\n/*\n throw new DuplicateError();\n ^\n Duplicate: Resource Unicorn (1) already exists\n at Object.\u003canonymous\u003e (/erroz/examples/staticErrorMessage.js:14:7)\n at Module._compile (module.js:456:26)\n at Object.Module._extensions..js (module.js:474:10)\n at Module.load (module.js:356:32)\n at Function.Module._load (module.js:312:12)\n at Function.Module.runMain (module.js:497:10)\n at startup (node.js:119:16)\n at node.js:902:3\n */\n```\n\n## Installation\n\n`npm install --save erroz`\n\n## Defining errors\n\n```javascript\nconst errorDefinition = {\n  name: \"NotFound\",\n  template: \"%resource (%id) not found\",\n};\n\nconst NotFoundError = erroz(errorDefinition);\n```\n\n### errorDefinition _object_\n\nArbitrary data structure for metadata which will be available on every error\ninstance. Some attributes have a special meaning which is why they are described\nbelow:\n\n#### `name` _string_\n\nThe name displayed when the error is thrown.\n\n#### `message` _string_\n\nA static error message.\n\n#### `template` _string_\n\nA dynamic error message. Variable substitution from\n[the data object](https://github.com/peerigon/erroz#throwing-with-data-object)\nis done with `%\u003cvariable name\u003e`.\n\n## Throwing (with data object)\n\n```javascript\nconst data = { resource: \"Unicorn\", id: 1 };\nthrow new NotFoundError(data);\n// Duplicate: Resource Unicorn (1) already exists\n```\n\n### data _object_\n\nA set of data to be used with\n[the `errorDefinition.template` property](https://github.com/peerigon/erroz#template-string).\n\n## Throwing (with error message)\n\n```javascript\nconst overrideMessage = \"You are not authorized to eat my cookies\";\n\nthrow new ForbiddenError(overrideMessage);\n// Forbidden: You are not authorized to eat my cookies\n```\n\n### overrideMessage _string_\n\nA message to override `errorDefinition.message` or `errorDefinition.template`.\nUse of this option will set `error.data` to an empty object.\n\n## JSON\n\nErrors can be converted to JSON with `JSON.stringify()`.\n\n```javascript\nconst err = new DuplicateError({ resource: \"Unicorn\", id: 1 });\n\nconsole.log(JSON.stringify(err));\n\n/*\n {\n    \"name\": \"Duplicate\",\n    \"code\": \"duplicate\",\n    \"status\": \"fail\",\n    \"statusCode\": 409,\n    \"template\": \"Resource %resource (%id) already exists\",\n    \"data\": {\n        \"resource\": \"Unicorn\",\n        \"id\": 1\n    },\n    \"message\": \"Resource Unicorn (1) already exists\"\n }\n */\n```\n\n**Custom JSON format**\n\nThe `options.toJSON` method can be defined to customize the JSON format.\n\n```javascript\nimport { erroz } from \"erroz\";\n\n// Set a custom `toJSON` method for all errors\nerroz.options.toJSON = function () {\n  return {\n    name: this.name,\n    code: this.code,\n  };\n};\n\nconst DuplicateError = erroz(errorConfig);\n\nconsole.log(JSON.stringify(new DuplicateError()));\n/*\n {\n    \"name\": \"Duplicate\",\n    \"code\": \"duplicate\"\n }\n */\n```\n\n### `error.toJSend()`\n\nConverts the error to a JSend-style object. The JSend `status` attribute is\nderived from the statusCode if not passed explicitly. Valid codes are 4xx and\n5xx. In case of an invalid statusCode, `.toJSend()` will throw an error.\n\n```javascript\nconst err = new DuplicateError({ resource: \"Unicorn\", id: 1, status: 409 });\n\nerr.toJSend();\n\n/*\n {\n    \"status\": \"fail\",\n    \"code\": \"duplicate\",\n    \"message\": \"Resource Unicorn (1) already exists\",\n    \"data\": {\n    \t\"resource\": \"Unicorn\",\n    \t\"id\": 1,\n    \t\"stack\": \"Duplicate: Resource Unicorn (1) already exists\\n    at Object.\u003canonymous\u003e (/erroz/examples/\t\t\t\t  toJson.js:13:11)\\n    at Module._compile (module.js:\t\t\t\t  456:26)\\n    at Object.Module._extensions..js (module.js:474:10)\\n    at Module.load \t\t\t\t  (module.js:356:32)\\n    at Function.Module._load (module.js:312:12)\\n    at \t\t\t     Function.Module.runMain (module.js:497:10)\\n    at startup (node.js:119:16)\\n    at node.js:\t\t\t\t  906:3\"\n    \t}\n}\n*/\n```\n\n## Options\n\n### renderMessage _function_\n\nDefine a custom error renderer.\n\n```javascript\nerroz.options.renderMessage = function (data, template) {\n  return \"Ooops\";\n};\n```\n\n### includeStack _boolean_\n\nWhether the stack should be included in errors. Default is true.\n\n```javascript\nerroz.options.includeStack = false;\n```\n\nConsider turning this off in production and sending it to a logger instead.\n\n## Pro Tip: Using erroz with Connect / Express error handlers\n\nDefine a global error handler which calls `toJSend()` if the error is an\ninstance of `erroz.AbstractError`. **why do this?** So you can simply `next` all\nyour errors in your route-handlers.\n\n```javascript\nfunction myAwesomeRoute(req, res, next) {\n  if (!req.awesome) {\n    next(new NotAwesomeError());\n    return;\n  }\n\n  next();\n}\n```\n\n```javascript\napp.use(function errozHandler(err, req, res, next) {\n  if (err instanceof erroz.AbstractError) {\n    res.status(err.statusCode).send(err.toJSend());\n    return;\n  }\n\n  // Pass on all non-erroz errors\n  next(err);\n});\n```\n\n## Licence\n\nMIT\n\n## Sponsors\n\n[\u003cimg src=\"https://assets.peerigon.com/peerigon/logo/peerigon-logo-flat-spinat.png\" width=\"150\" /\u003e](https://peerigon.com)\n","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeerigon%2Ferroz","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpeerigon%2Ferroz","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeerigon%2Ferroz/lists"}