{"id":28713926,"url":"https://github.com/xvezda/eslint-plugin-explicit-exceptions","last_synced_at":"2025-09-13T03:36:27.466Z","repository":{"id":294789973,"uuid":"987411563","full_name":"Xvezda/eslint-plugin-explicit-exceptions","owner":"Xvezda","description":"ESLint rules for explicitly handling hidden exceptions","archived":false,"fork":false,"pushed_at":"2025-06-28T00:05:45.000Z","size":529,"stargazers_count":19,"open_issues_count":4,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-08-29T19:24:52.805Z","etag":null,"topics":["best-practices","eslint","eslint-plugin","eslint-rules","exception-handling","exceptions","jsdoc","plugin","rules","tslint","typescript","typescript-eslint"],"latest_commit_sha":null,"homepage":"http://npm.im/eslint-plugin-explicit-exceptions","language":"JavaScript","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/Xvezda.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,"zenodo":null}},"created_at":"2025-05-21T03:25:57.000Z","updated_at":"2025-08-18T06:21:32.000Z","dependencies_parsed_at":"2025-05-22T04:26:45.622Z","dependency_job_id":"7ad8a8a6-daba-44e2-b82a-a7b0a8e2c401","html_url":"https://github.com/Xvezda/eslint-plugin-explicit-exceptions","commit_stats":null,"previous_names":["xvezda/eslint-plugin-explicit-exceptions"],"tags_count":29,"template":false,"template_full_name":null,"purl":"pkg:github/Xvezda/eslint-plugin-explicit-exceptions","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Xvezda%2Feslint-plugin-explicit-exceptions","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Xvezda%2Feslint-plugin-explicit-exceptions/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Xvezda%2Feslint-plugin-explicit-exceptions/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Xvezda%2Feslint-plugin-explicit-exceptions/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Xvezda","download_url":"https://codeload.github.com/Xvezda/eslint-plugin-explicit-exceptions/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Xvezda%2Feslint-plugin-explicit-exceptions/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274915145,"owners_count":25373189,"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-09-13T02:00:10.085Z","response_time":70,"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":["best-practices","eslint","eslint-plugin","eslint-rules","exception-handling","exceptions","jsdoc","plugin","rules","tslint","typescript","typescript-eslint"],"created_at":"2025-06-15T01:00:50.088Z","updated_at":"2025-09-13T03:36:27.455Z","avatar_url":"https://github.com/Xvezda.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# eslint-plugin-explicit-exceptions\n\n[![NPM Version](https://img.shields.io/npm/v/eslint-plugin-explicit-exceptions)](https://www.npmjs.com/package/eslint-plugin-explicit-exceptions)\n[![Coverage](https://raw.githubusercontent.com/Xvezda/eslint-plugin-explicit-exceptions/refs/heads/_meta/coverage.svg)](https://github.com/Xvezda/eslint-plugin-explicit-exceptions/actions/workflows/test.yml)\n[![Test](https://github.com/Xvezda/eslint-plugin-explicit-exceptions/actions/workflows/test.yml/badge.svg)](https://github.com/Xvezda/eslint-plugin-explicit-exceptions/actions/workflows/test.yml)\n\nhttps://github.com/user-attachments/assets/4a833442-b8a5-462f-abeb-a28bd0e5863f\n\nJust as [Java’s throws keyword](https://dev.java/learn/exceptions/throwing/) does, enforcing the use of [JSDoc’s `@throws` tag](https://jsdoc.app/tags-throws) to explicitly specify which exceptions a function can throw to solve unpredictable propagation of exceptions happening which also known as a [JavaScript's \"hidden exceptions\"](https://www.youtube.com/watch?v=3iWoNJbGO2U).\n\n## Features\n- Reports and provides fixes for throwable functions that are not annotated with `@throws`.\n- Reports and provides fixes for async functions and Promise rejections.\n- Verifies that the exception types match the documented types.\n\n## Examples\nFor functions that propagate exceptions to the caller because they didn’t handle exceptions, this plugin enforces the use of a `@throws` comment.\n```javascript\n// ❌ Error - no `@throws` tag\nfunction foo() {\n  throw new RangeError();\n}\n\n// ✅ OK - no exception propagation\nfunction bar() {\n  try {\n    throw new TypeError();\n  } catch {}\n}\n\n// ❌ Error\nfunction baz() {\n  maybeThrow();\n}\n\n// ✅ OK\n/** @throws {Error} */\nfunction qux() {\n  maybeThrow();\n}\n```\n\nIt also leverages these comments for type checking, helping ensure that errors are handled safely.\n```javascript\n// ❌ Error - type mismatch\n/** @throws {TypeError} */\nfunction foo() {\n  throw new RangeError();\n}\n\n// ✅ OK\n/**\n * @throws {TypeError}\n * @throws {RangeError}\n */\nfunction bar() {\n  maybeThrowTypeError();\n  maybeThrowRangeError();\n}\n\n// ✅ OK\n/** @throws {number} */\nfunction baz() {\n  throw 42;\n}\n\n// ✅ OK\n/**\n * @throws {\"error\"}\n */\nfunction qux() {\n  throw 'error';\n}\n```\n\nFor error classes, since TypeScript uses duck typing for type checking, this plugin treats inherited error classes as different types.\nHowever, documenting a common parent class is permitted.\n```javascript\n// ✅ OK\n/** @throws {RangeError | TypeError} */\nfunction foo() {\n  maybeThrowRangeError();\n  maybeThrowTypeError();\n}\n\n// ✅ OK\n/** @throws {Error} */\nfunction bar() {\n  maybeThrowRangeError();\n  maybeThrowTypeError();\n}\n```\n\nTo clearly distinguish between a synchronous throw and an asynchronous promise rejection, this plugin requires that promise rejections be documented in the special form of `Promise\u003cError\u003e`.\n```javascript\n/**\n * @throws {Promise\u003cError\u003e}\n */\nfunction foo() {\n  return new Promise((resolve, reject) =\u003e reject(new Error()));\n}\n\n/**\n * @throws {Promise\u003cTypeError | RangeError\u003e}\n */\nasync function bar() {\n  if (randomBool()) {\n    throw new TypeError();  // This becomes promise rejection\n  } else {\n    return maybeThrowRangeError();\n  }\n}\n```\nFor more examples, check out [examples](https://github.com/Xvezda/eslint-plugin-explicit-exceptions/tree/master/examples) directory and rules below.\n\n## Rules\n - [`no-undocumented-throws`](https://github.com/Xvezda/eslint-plugin-explicit-exceptions/blob/master/docs/rules/no-undocumented-throws.md)\n - [`check-throws-tag-type`](https://github.com/Xvezda/eslint-plugin-explicit-exceptions/blob/master/docs/rules/check-throws-tag-type.md)\n\n## Usage\n\nInstall dependencies\n```sh\n# https://typescript-eslint.io/getting-started/#step-1-installation\nnpm install --save-dev eslint @eslint/js typescript typescript-eslint\n```\n\nInstall plugin\n```\nnpm install --save-dev eslint-plugin-explicit-exceptions\n```\n\n\u003e [!WARNING]\n\u003e \u003e These packages are experimental.\n\u003e \n\u003e Install custom types for better built-in, libraries lint support.\n\u003e ```sh\n\u003e # For @types/*, i.e. @types/node\n\u003e npm install --save-dev @types-with-exceptions/node\n\u003e # For built-in lib replacement\n\u003e npm install --save-dev @types-with-exceptions/lib\n\u003e ```\n\u003e `tsconfig.json`\n\u003e ```diff\n\u003e  {\n\u003e     // ...\n\u003e +   \"typeRoots\": [\n\u003e +     \"node_modules/@types\",\n\u003e +     \"node_modules/@types-with-exceptions\"\n\u003e +   ],\n\u003e +   \"libReplacement\": true,\n\u003e     // ...\n\u003e  }\n\u003e ```\n\u003e Visit https://github.com/Xvezda/types-with-exceptions to see more.\n\n\u003e [!NOTE]\n\u003e I'm working on documentation for frequently used APIs.  \n\u003e https://github.com/Xvezda/types-with-exceptions  \n\u003e However, it's still not usable. As a temporary workaround, you can extend the type interfaces in your own type definitions.\n\u003e ```typescript\n\u003e // e.g. Promise.reject()\n\u003e interface PromiseConstructor {\n\u003e   /**\n\u003e    * @throws {Promise\u003cunknown\u003e}\n\u003e    */\n\u003e   reject(reason?: any): Promise\u003cunknown\u003e;\n\u003e }\n\u003e ```\n\nCreate `eslint.config.mjs`\n\n```javascript\n// @ts-check\n\nimport eslint from '@eslint/js';\nimport tseslint from 'typescript-eslint';\nimport explicitExceptionsLint from 'eslint-plugin-explicit-exceptions';\n\nexport default tseslint.config(\n  eslint.configs.recommended,\n  tseslint.configs.recommended,\n  explicitExceptionsLint.configs.recommendedTypeChecked,\n  {\n    languageOptions: {\n      parserOptions: {\n        projectService: true,\n        tsconfigRootDir: import.meta.dirname,\n      },\n    },\n  },\n);\n```\n\nFor legacy, `.eslintrc.json`\n\n```json\n{\n  \"extends\": [\n    \"eslint:recommended\",\n    \"plugin:eslint-plugin-explicit-exceptions/recommended-type-checked-legacy\"\n  ],\n  \"parser\": \"@typescript-eslint/parser\",\n  \"plugins\": [\"@typescript-eslint\"],\n  \"parserOptions\": {\n    \"projectService\": true\n  },\n  \"root\": true\n}\n```\nThis project uses [TypeScript](https://www.typescriptlang.org/) and [typescript-eslint](https://typescript-eslint.io/) to leverage type information. To prevent errors or bugs caused by incorrect type data, it is recommended to [set the `tsconfig.json` `\"strict\"` option to `true`](https://www.typescriptlang.org/tsconfig/#strict).\n\nCheck out [`typescript-eslint`](https://typescript-eslint.io/getting-started/) for more information if you having an issue with configuring.\n\n## License\n[MIT License](https://github.com/Xvezda/eslint-plugin-explicit-exceptions/blob/master/LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxvezda%2Feslint-plugin-explicit-exceptions","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxvezda%2Feslint-plugin-explicit-exceptions","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxvezda%2Feslint-plugin-explicit-exceptions/lists"}