{"id":18431521,"url":"https://github.com/ahmedadelfahim/unified-errors-handler","last_synced_at":"2025-04-07T18:32:54.739Z","repository":{"id":242888736,"uuid":"809618992","full_name":"AhmedAdelFahim/unified-errors-handler","owner":"AhmedAdelFahim","description":"Unified Errors Handler is  A Powerful Error Handling Library for Node.js that unify error structure across application. it can unify database errors.","archived":false,"fork":false,"pushed_at":"2024-06-29T15:00:34.000Z","size":620,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-08-31T12:18:17.688Z","etag":null,"topics":["error-handling","express","mysql","objectionjs","postgresql","sequelize-orm","unified-errors"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/unified-errors-handler","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/AhmedAdelFahim.png","metadata":{"files":{"readme":"README.md","changelog":null,"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":"2024-06-03T05:59:47.000Z","updated_at":"2024-06-25T11:57:53.000Z","dependencies_parsed_at":"2024-06-29T16:21:37.937Z","dependency_job_id":null,"html_url":"https://github.com/AhmedAdelFahim/unified-errors-handler","commit_stats":null,"previous_names":["ahmedadelfahim/unified-errors-handler"],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AhmedAdelFahim%2Funified-errors-handler","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AhmedAdelFahim%2Funified-errors-handler/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AhmedAdelFahim%2Funified-errors-handler/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AhmedAdelFahim%2Funified-errors-handler/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AhmedAdelFahim","download_url":"https://codeload.github.com/AhmedAdelFahim/unified-errors-handler/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223288653,"owners_count":17120441,"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-handling","express","mysql","objectionjs","postgresql","sequelize-orm","unified-errors"],"created_at":"2024-11-06T05:25:11.825Z","updated_at":"2025-04-07T18:32:54.731Z","avatar_url":"https://github.com/AhmedAdelFahim.png","language":"TypeScript","readme":"# Unified Errors Handler\nUnified Errors Handler is an advanced error-handling library for Node.js. It standardizes error structures across Express.js, NestJS, and databases like MySQL, PostgreSQL, and MongoDB. It simplifies debugging, improves consistency, and enhances error logging.\n\n[![Latest Stable Version](https://img.shields.io/npm/v/unified-errors-handler.svg?style=for-the-badge)](https://www.npmjs.com/package/unified-errors-handler)\n![GitHub License](https://img.shields.io/github/license/AhmedAdelFahim/unified-errors-handler?style=for-the-badge)\n[![NPM Downloads](https://img.shields.io/npm/dt/unified-errors-handler.svg?style=for-the-badge)](https://www.npmjs.com/package/unified-errors-handler)\n[![NPM Downloads](https://img.shields.io/npm/dm/unified-errors-handler.svg?style=for-the-badge)](https://www.npmjs.com/package/unified-errors-handler)\n\n\u003cp style=\"text-align: center;\"\u003e\u003ci\u003eUnified Errors Handler simplifies error handling in Node.js, Express, and NestJS. Supports Sequelize, TypeORM, Objection.js, Mongoose, and Knex.js.\u003c/i\u003e\u003c/p\u003e\n\n## [Full Documentation](https://nodejs-unified-errors-handler-docs.vercel.app/)\n\n## Content\n\n1. [Installation](https://www.npmjs.com/package/unified-errors-handler#installation)\n2. [How to Use Unified Errors Handler in Node.js](https://www.npmjs.com/package/unified-errors-handler#usage)\n    1. [ExpressJS Middleware](https://www.npmjs.com/package/unified-errors-handler#expressjs-middleware)\n    2. [Custom ExpressJS Middleware](https://www.npmjs.com/package/unified-errors-handler#custom-expressjs-middleware)\n    3. [NestJS Exception Filter](https://www.npmjs.com/package/unified-errors-handler#nestjs-exception-filter)\n    4. [Options](https://www.npmjs.com/package/unified-errors-handler#options)\n3. [Errors Structure](https://www.npmjs.com/package/unified-errors-handler#unified-structure)\n4. [General Exceptions](https://www.npmjs.com/package/unified-errors-handler#exceptions)\n5. [SQL Database Exceptions](https://www.npmjs.com/package/unified-errors-handler#sql-database-exceptions)\n6. [No SQL Database Exceptions](https://www.npmjs.com/package/unified-errors-handler#no-sql-database-exceptions)\n7. [Custom Exceptions](https://www.npmjs.com/package/unified-errors-handler#custom-exceptions)\n8. [Logging](https://www.npmjs.com/package/unified-errors-handler#logging)\n9. [See supported ORMs](https://www.npmjs.com/package/unified-errors-handler#see-supported-orms)\n10. [Tests](https://www.npmjs.com/package/unified-errors-handler#tests)\n11. [Support and Suggestions](https://www.npmjs.com/package/unified-errors-handler#support-and-suggestions)\n\n## Installation\n\n```bash\n$ npm install unified-errors-handler\n```\n## How to Use Unified Errors Handler in Node.js\n* #### ExpressJS Middleware\n\n```javascript\nconst express = require('express');\nconst { expressExceptionHandler } = require('unified-errors-handler');\nconst app = express();\n/**\n  response in case of error will be\n  {\n    errors: [\n      {\n        code: 'USER_NOT_FOUND',\n        message: 'user not found',\n      },\n    ],\n  }\n  with status code 404\n*/\napp.post('/test', function (req, res) {\n    const isFound = // ...\n    if (isFound) {\n      // return response\n    } else {\n      throw new NotFoundException([\n        {\n          code: 'USER_NOT_FOUND',\n          message: 'user not found',\n        },\n      ]);\n    }\n});\n\napp.use(expressExceptionHandler());\n```\n* #### Custom ExpressJS Middleware\n\n```javascript\nconst express = require('express');\nconst { exceptionMapper } = require('unified-errors-handler');\n\nconst app = express();\n/**\n  response in case of error will be\n  {\n    errors: [\n      {\n        code: 'USER_NOT_FOUND',\n        message: 'user not found',\n      },\n    ],\n  }\n  with status code 404\n*/\napp.post('/test', function (req, res) {\n    const isFound = // ...\n    if (isFound) {\n      // return response\n    } else {\n      throw new NotFoundException([\n        {\n          code: 'USER_NOT_FOUND',\n          message: 'user not found',\n        },\n      ]);\n    }\n});\n\napp.use((err: Error, req: any, res: any, next: any) =\u003e {\n    const mappedError = exceptionMapper(err);\n   \n    res.status(mappedError.statusCode).send({\n      errors: mappedError.serializeErrors(),\n    });\n  });\n```\n\n* #### NestJS Exception Filter\n```javascript\nconst { exceptionMapper } = require('unified-errors-handler');\n\n@Catch()\nexport class AllExceptionsFilter implements ExceptionFilter {\n  catch(exception: unknown, host: ArgumentsHost) {\n    const ctx = host.switchToHttp();\n    const response = ctx.getResponse\u003cResponse\u003e();\n\n    const error = exceptionMapper(exception);\n    const statusCode = error.statusCode;\n    response.status(statusCode).json({\n      errors: error.serializeErrors(),\n    });\n  }\n}\n```\n\n* #### Options\nYou can add options to (enable/disable) parsing for database errors (depends on your ORM) this is disabled by default, [See supported ORMs](https://www.npmjs.com/package/unified-errors-handler#see-supported-orms)\n\n```javascript\nconst options = {\n    mapDBExceptions: true,            // deprecated\n    parseSequelizeExceptions: true,\n    parseMongooseExceptions: true,\n    parseTypeORMExceptions: true,\n    parseObjectionJSExceptions: true,\n    parseKnexJSExceptions: false,\n}\n\nexpressExceptionHandler(options)\n// or \nconst mappedError = exceptionMapper(err, options);\n```\n\n## Unified Structure\n```javascript\n{\n   errors: [{\n      fields: ['name', 'password'],   // optional\n      code: 'YOUR_CODE',\n      message: 'your message'\n      details: {    // optional - more details about error\n        key: value \n      }\n   }]\n}\n```\n\n## Exceptions\n1. #### BadRequestException\n* Status code - 400  \n```javascript\nthrow new BadRequestException({\n  fields: ['password'],        // optional\n  code: 'INVALID_PASSWORD',    // optional\n  message: 'invalid password'\n  details: {                  // optional\n   // ... more details\n  }\n});\n```\n2. #### UnauthorizedException\n* Status code - 401\n```javascript\nthrow new UnauthorizedException({\n  code: 'UNAUTHORIZED',\n  message: 'You are not authorized'\n});\n```\n3. #### ForbiddenException\n* Status code - 403\n```javascript\nthrow new ForbiddenException({\n  code: 'FORBIDDEN',\n  message: 'You have no access'\n});\n```\n4. #### NotFoundException\n* Status code - 404\n```javascript\nthrow new NotFoundException([\n  {\n     code: 'USER_NOT_FOUND',\n     message: 'user not found',\n  },\n]);\n```\n5. #### ServerException\n* Status code - 500\n```javascript\nthrow new ServerException();\n```\n## SQL Database Exceptions\n1. #### UniqueViolationException\n* Status code - 400  \n```javascript\n// output\n[\n  {\n    fields: ['name'],\n    code: 'DATA_ALREADY_EXIST',\n    message: 'name already exist',\n  },\n]\n```\n2. #### ForeignKeyViolationException\n* Status code - 400  \n```javascript\n// output\n// foreign key is not exist as primary key in another table\n// trying insert value with invalid foreign key\n[\n  code: 'INVALID_DATA',\n  message: 'Invalid data',\n  details: {\n    reason: 'violates foreign key constraint',\n    constraint: 'pet_user_id_foreign',\n  },\n]\n// foreign key has reference in another table \n[\n  code: 'DATA_HAS_REFERENCE',\n  message: 'Data has reference',\n  details: {\n    reason: 'violates foreign key constraint',\n    constraint: 'pet_user_id_foreign',\n  },\n]\n```\n3. #### NotNullViolationException\n* Status code - 400  \n```javascript\n// output\n[\n  {\n    fields: ['age'],\n    code: 'INVALID_DATA',\n    message: 'age is invalid',\n    details: { reason: 'age must not be NULL' },\n  },\n]\n```\n4. #### CheckViolationException\n* Status code - 400  \n* Example - Invalid enum value\n```javascript\n// output\n[{\n  code: 'INVALID_VALUES',\n  message: 'Invalid Values',\n  details: {\n    constraint: 'user_gender_check',\n  },\n}]\n```\n5. #### OutOfRangeViolationException\n* Status code - 400  \n* Example - numeric value out of range \n```javascript\n// output\n[{\n  {\n    code: 'OUT_OF_RANGE',\n    message: 'Out of range',\n  },\n}]\n```\n## No SQL Database Exceptions\n1. #### MongoDBUniqueViolationException\n* Status code - 400  \n```javascript\n// output\n[\n  {\n    fields: ['name'],\n    values: ['Ahmed'],\n    code: 'DATA_ALREADY_EXIST',\n    message: 'name already exist',\n  },\n]\n```\n2. #### MongooseValidationException\n* Status code - 400  \n```javascript\n// output\n[\n  // field is required\n  {\n    fields: ['age'],\n    message: 'Path `age` is required.',\n    code: 'MONGODB_VALIDATION_ERROR',\n    details: { \n      reason: 'age is required', \n      violate: 'required_validation'\n    },\n  },\n  // field's value violate enum values\n  {\n    fields: ['gender'],\n    message: '`MALEE` is not a valid enum value for path `gender`.',\n    code: 'MONGODB_VALIDATION_ERROR',\n    details: { \n      reason: \"gender's value must be one of MALE, FEMALE\", \n      violate: 'enum_validation'\n    },\n  },\n  // field's value violate max value\n  {\n    fields: ['age'],\n    message: 'Path `age` (300) is more than maximum allowed value (50).',\n    code: 'MONGODB_VALIDATION_ERROR',\n    details: { \n      reason: `age's value exceed maximum allowed value (50)`, \n      violate: 'max_validation'\n    },\n  },\n  // field's value violate min value\n  {\n    fields: ['age'],\n    message: 'Path `age` (3) is less than minimum allowed value (20).',\n    code: 'MONGODB_VALIDATION_ERROR',\n    details: { \n      reason: `age's value less than minimum allowed value (20)`, \n      violate: 'min_validation'\n    },\n  },\n  // field's value violate type of field\n  {\n    fields: ['age'],\n    message: 'age is invalid',\n    code: 'MONGODB_CASTING_ERROR',\n  },\n]\n```\n\n## Custom Exceptions\nYou can create your own exceptions by extending `BaseException`.\n```javascript\nexport class MyCustomException extends BaseException {\n  statusCode = 400;\n\n  constructor(private message: string) {\n    super(message);\n    Object.setPrototypeOf(this, MyCustomException.prototype);\n  }\n\n  serializeErrors() {\n    return [{\n      message,\n      code: 'CUSTOM_CODE'\n    }];\n  }\n}\n```\n\n## Logging\n1. #### ConsoleLogger\n```javascript\nconst options = {\n  loggerOptions: {\n    console: {\n      format: ':time :message', // optional - default message only\n      colored: true,    // optional - default no color\n    },\n  },\n}\n\nexpressExceptionHandler(options)\n// or \nconst mappedError = exceptionMapper(err, options);\n```\n2. #### CustomLogger\nimplement ILogger interface\n```javascript\nimport { ILogger } from 'unified-errors-handler';\n\nclass CustomLogger implements ILogger {\n  log(error: any): void {\n    console.log(error.message);\n  }\n}\n\n// in options pass this object\nconst options = {\n  loggerOptions: {\n    custom: new CustomLogger(),\n  },\n}\n\nexpressExceptionHandler(options)\n// or \nconst mappedError = exceptionMapper(err, options);\n```\n\n## Supported Database and ORMs\n1. MYSQL with [TypeORM](https://typeorm.io)\n2. Postgres with [TypeORM](https://typeorm.io)\n3. MYSQL with [Sequelize](https://www.npmjs.com/package/sequelize)\n4. Postgres with [Sequelize](https://www.npmjs.com/package/sequelize)\n5. MYSQL with [ObjectionJS](https://www.npmjs.com/package/objection)\n6. Postgres with [ObjectionJS](https://www.npmjs.com/package/objection)\n5. MYSQL with [KnexJS](https://knexjs.org)\n6. Postgres with [KnexJS](https://knexjs.org)\n7. MongoDB with [Mongoose](https://www.npmjs.com/package/mongoose)\n\n\n## Tests\nTo run the test suite, \n1. first install the dependencies\n2. rename .env.sample to .env \n3. You can run `docker-comose up` or set your own connection URLs for postgres database and mysql database in .env\n4. run `npm test`:\n```bash\n$ npm install\n$ npm test\n```\n## Support and Suggestions\nFeel free to open issues on [github](https://github.com/AhmedAdelFahim/unified-errors-handler).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fahmedadelfahim%2Funified-errors-handler","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fahmedadelfahim%2Funified-errors-handler","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fahmedadelfahim%2Funified-errors-handler/lists"}