1"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([["2761"],{77614(e,r,n){n.r(r),n.d(r,{metadata:()=>s,default:()=>p,frontMatter:()=>a,contentTitle:()=>c,toc:()=>d,assets:()=>u});var s=JSON.parse('{"id":"prefer-promise-reject-errors","title":"prefer-promise-reject-errors","description":"Require using Error objects as Promise rejection reasons.","source":"@site/../eslint-plugin/docs/rules/prefer-promise-reject-errors.mdx","sourceDirName":".","slug":"/prefer-promise-reject-errors","permalink":"/rules/prefer-promise-reject-errors","draft":false,"unlisted":false,"editUrl":"https://github.com/typescript-eslint/typescript-eslint/edit/main/packages/website/../eslint-plugin/docs/rules/prefer-promise-reject-errors.mdx","tags":[],"version":"current","frontMatter":{"description":"Require using Error objects as Promise rejection reasons.","image":"/img/og/rules/prefer-promise-reject-errors.png"},"sidebar":"rulesSidebar","previous":{"title":"prefer-optional-chain","permalink":"/rules/prefer-optional-chain"},"next":{"title":"prefer-readonly","permalink":"/rules/prefer-readonly"}}'),t=n(65723),o=n(7143),l=n(70503),i=n(46742);let a={description:"Require using Error objects as Promise rejection reasons.",image:"/img/og/rules/prefer-promise-reject-errors.png"},c,u={},d=[{value:"Examples",id:"examples",level:2},{value:"How to Use",id:"how-to-use",level:2},{value:"Options",id:"options",level:2},{value:"<code>allow</code>",id:"allow",level:3},{value:"<code>allowThrowingAny</code>",id:"allowthrowingany",level:3},{value:"<code>allowThrowingUnknown</code>",id:"allowthrowingunknown",level:3},{value:"When Not To Use It",id:"when-not-to-use-it",level:2},{value:"Resources",id:"resources",level:2}];function h(e){let r={a:"a",blockquote:"blockquote",code:"code",h2:"h2",h3:"h3",li:"li",meta:"meta",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.R)(),...e.components},{BaseRuleReference:n,Head:s,RuleAttributes:a,TryInPlayground:c}=r;return n||m("BaseRuleReference",!0),s||m("Head",!0),a||m("RuleAttributes",!0),c||m("TryInPlayground",!0),(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(t.Fragment,{children:(0,t.jsxs)(r.blockquote,{children:["\n",(0,t.jsx)(r.p,{children:"Require using Error objects as Promise rejection reasons."}),"\n"]})}),"\n",(0,t.jsx)(a,{name:"prefer-promise-reject-errors"}),"\n","\n",(0,t.jsxs)(r.p,{children:["This rule extends the base ",(0,t.jsx)(r.a,{href:"https://eslint.org/docs/latest/rules/prefer-promise-reject-errors",children:(0,t.jsx)(r.code,{children:"prefer-promise-reject-errors"})})," rule from ESLint core."," ","It uses type information to enforce that ",(0,t.jsx)(r.code,{children:"Promise"}),"s are only rejected with ",(0,t.jsx)(r.code,{children:"Error"})," objects."]}),"\n",(0,t.jsx)(r.h2,{id:"examples",children:"Examples"}),"\n",(0,t.jsxs)(l.A,{children:[(0,t.jsx)(i.A,{value:"\u274C Incorrect",children:(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-ts",metastring:'eslintrcHash="N4KABGBEBOCuA2BTAzpAXGUEKQA7UQDNFoBafAewFsBLZRUggK0QGMAXUk6C6VDSBUKFIAGnDZIAAXYBPXClbQauTing0AduwD0+IiXI9a9RohYcu0Hn3RRuvSBIC+IZ0A"',children:"Promise.reject('error');\n\nconst err = new Error();\nPromise.reject('an ' + err);\n\nnew Promise((resolve, reject) => reject('error'));\n\nnew Promise((resolve, reject) => {\n const err = new Error();\n reject('an ' + err);\n});\n"})})}),(0,t.jsx)(i.A,{value:"\u2705 Correct",children:(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-ts",metastring:'eslintrcHash="N4KABGBEBOCuA2BTAzpAXGUEKQA7UQDNFoBafAewFsBLZRUggK0QGMAXUk6C6VDSBUKFIAGnDZIAAXYBPXClbQauTing0AduwD0+IiXI9a9RohYcu0Hn3RRuvSBIC+IZ0A"',children:"Promise.reject(new Error());\n\nclass CustomError extends Error {\n // ...\n}\nPromise.reject(new CustomError());\n\nnew Promise((resolve, reject) => reject(new Error()));\n\nnew Promise((resolve, reject) => {\n class CustomError extends Error {\n // ...\n }\n return reject(new CustomError());\n});\n"})})})]}),"\n",(0,t.jsx)(r.h2,{id:"how-to-use",children:"How to Use"}),"\n",(0,t.jsxs)(l.A,{children:[(0,t.jsx)(i.A,{value:"Flat Config",children:(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-js",metastring:'title="eslint.config.mjs"',children:'export default defineConfig({\n rules: {\n // Note: you must disable the base rule as it can report incorrect errors\n "prefer-promise-reject-errors": "off",\n "@typescript-eslint/prefer-promise-reject-errors": "error"\n }\n});\n'})})}),(0,t.jsx)(i.A,{value:"Legacy Config",children:(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-js",metastring:'title=".eslintrc.cjs"',children:'module.exports = {\n "rules": {\
1n // Note: you must disable the base rule as it can report incorrect errors\n "prefer-promise-reject-errors": "off",\n "@typescript-eslint/prefer-promise-reject-errors": "error"\n }\n};\n'})})})]}),"\n",(0,t.jsx)(c,{eslintrcHash:"N4KABGBEBOCuA2BTAzpAXGUEKQA7UQDNFoBafAewFsBLZRUggK0QGMAXUk6C6VDSBUKFIAGnDZIAAXYBPXClbQauTing0AduwD0+IiXI9a9RohYcu0Hn3RRuvSBIC+IZ0A",children:(0,t.jsx)(r.p,{children:"Try this rule in the playground \u2197"})}),"\n",(0,t.jsx)(r.h2,{id:"options",children:"Options"}),"\n",(0,t.jsx)(t.Fragment,{children:(0,t.jsxs)(r.p,{children:["See ",(0,t.jsxs)(r.a,{href:"https://eslint.org/docs/rules/prefer-promise-reject-errors#options",children:[(0,t.jsx)(r.code,{children:"eslint/prefer-promise-reject-errors"}),"'s options"]}),"."]})}),"\n",(0,t.jsx)(r.p,{children:"This rule adds the following options:"}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-ts",children:"interface Options {\n /**\n * Type specifiers that can be used as Promise rejection reasons.\n */\n allow?: (\n | {\n from: 'file';\n name: string[] | string;\n path?: string;\n }\n | {\n from: 'lib';\n name: string[] | string;\n }\n | {\n from: 'package';\n name: string[] | string;\n package: string;\n }\n | string\n )[];\n\n /**\n * Whether to always allow throwing values typed as `any`.\n */\n allowThrowingAny?: boolean;\n\n /**\n * Whether to always allow throwing values typed as `unknown`.\n */\n allowThrowingUnknown?: boolean;\n}\n\nconst defaultOptions: Options = {\n allow: [],\n allowThrowingAny: false,\n allowThrowingUnknown: false,\n};\n"})}),"\n",(0,t.jsx)(r.h3,{id:"allow",children:(0,t.jsx)(r.code,{children:"allow"})}),"\n",(0,t.jsx)(t.Fragment,{children:(0,t.jsxs)(r.p,{children:["Type specifiers that can be used as Promise rejection reasons. Default: ",(0,t.jsx)(r.code,{children:"[]"}),"."]})}),"\n","\n",(0,t.jsxs)(r.p,{children:["This option takes the shared ",(0,t.jsxs)(r.a,{href:"/packages/type-utils/type-or-value-specifier",children:[(0,t.jsx)(r.code,{children:"TypeOrValueSpecifier"})," format"]}),".\nIt can be useful for rejecting with error types defined by libraries that do not extend ",(0,t.jsx)(r.code,{children:"Error"}),"."]}),"\n",(0,t.jsx)(r.p,{children:"Examples of code for this rule with:"}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-jsonc",children:'{\n "allow": [{ "from": "file", "name": "CustomError" }],\n}\n'})}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-ts",metastring:'option=\'{ "allow": [{ "from": "file", "name": "CustomError" }] }\' showPlaygroundButton eslintrcHash="N4KABGBEBOCuA2BTAzpAXGUEKQA7UQDNFoBafAewFsBLZRUggK0QGMAXUk6C6VDSBUKFIAGnDZIAAXYBPXClbQauTing0AduwD0+IiXI9a9RohYcu0Hn3RgA2hOxRuvMU+xZnkgIbx4FADudo7e3l5hzpCExnbRNEjukd6Qmj5UiHEAwrDI7NQAotZuHmEAvqXYALqVFc41EBVlQA"',children:"class CustomError /* does NOT extend Error */ {\n // ...\n}\n\nPromise.reject(new CustomError());\n"})}),"\n",(0,t.jsx)(r.h3,{id:"allowthrowingany",children:(0,t.jsx)(r.code,{children:"allowThrowingAny"})}),"\n",(0,t.jsx)(t.Fragment,{children:(0,t.jsxs)(r.p,{children:["Whether to always allow throwing values typed as ",(0,t.jsx)(r.code,{children:"any"}),". Default: ",(0,t.jsx)(r.code,{children:"false"}),"."]})}),"\n","\n",(0,t.jsxs)(r.p,{children:["Examples of ",(0,t.jsx)(r.strong,{children:"correct"})," code with ",(0,t.jsx)(r.code,{children:"{ allowThrowingAny: true }"}),":"]}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-ts",metastring:'option=\'{ "allowThrowingAny": true }\' showPlaygroundButton eslintrcHash="N4KABGBEBOCuA2BTAzpAXGUEKQA7UQDNFoBafAewFsBLZRUggK0QGMAXUk6C6VDSBUKFIAGnDZIAAXYBPXClbQauTing0AduwD0+IiXI9a9RohYcu0Hn3RgA2hOxRuvMU+xZnkgIbx4FADuACoAFjyBWgDmAIKasnbscIgeEAC+HgC6EhlpQA"',children:"declare const value: any;\n\nPromise.reject(value);\n"})}),"\n",(0,t.jsx)(r.h3,{id:"allowthrowingunknown",children:(0,t.jsx)(r.code,{children:"allowThrowingUnknown"})}),"\n",(0,t.jsx)(t.Fragment,{children:(0,t.jsxs)(r.p,{children:["Whether to always allow throwing values typed as ",(0,t.jsx)(r.code,{children:"unknown"}),". Default: ",(0,t.jsx)(r.code,{children:"false"}),"."]})}),"\n","\n",(0,t.jsxs)(r.p,{children:["Examples of ",(0,t.jsx)(r.strong,{children:"correct"})," code with ",(0,t.jsx)(r.code,{children:"{ allowThrowingUnknown: true }"}),":"]}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-ts",metastring:'option=\'{ "allowThrowingUnknown": true }\' showPlaygroundButton eslintrcHash="N4KABGBEBOCuA2BTAzpAXGUEKQA7UQDNFoBafAewFsBLZRUggK0QGMAXUk6C6VDSBUKFIAGnDZIAAXYBPXClbQauTing0AduwD0+IiXI9a9RohYcu0Hn3RgA2hOxRuvMU+xZnkgIbx4FADuACoAFjyBWgDmAKqaANaaQZp27HCIHhAAvh4AuhI5WUA"',children:"declare const value: unknown;\n\nPromise.reject(value);\n"})}),"\n",(0,t.jsx)(r.h2,{id:"when-not-to-use-it",children:"When Not To Use It"}),"\n",(0,t.jsx)(t.Fragment,{children:(0,t.jsxs)(r.p,{children:["Type checked lint rules are more powerful than traditional lint rules, but also require configuring ",(0,t.jsx)(r.a,{href:"/getting-started/typed-linting",children:"type checked linting"}),"."]})}),"\n",(0,t.jsx)(t.Fragment,{children:(0,t.jsxs)(r.p,{children:["See ",(0,t.jsx)(r.a,{href:"/troubleshooting/typed-linting/performance",children:"Troubleshooting > Linting with Type Information > Performance"})," if you experience performance degradations after enabling type checked rules."]})}),"\n",(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(r.h2,{id:"resources",children:"Resources"}),"\n",(0,t.jsxs)(r.ul,{children:["\n",(0,t.jsx)(r.li,{children:(0,t.jsx)(r.a,{href:"https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/src/rules/prefer-promise-reject-errors.ts",children:"Rule source"})}),"\n",(0,t.jsx)(r.li,{children:(0,t.jsx)(r.a,{href:"https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/tests/rules/prefer-promise-reject-errors.test.ts",children:"Test source"})}),"\n"]})]}),"\n",(0,t.jsx)(n,{baseRule:"prefer-promise-reject-errors",children:(0,t.jsx)(r.p,{children:"Try this rule in the playground \u2197"})}),"\n",(0,t.jsx)(s,{children:(0,t.jsx)(r.meta,{content:"prefer-promise-reject-errors: Require using Error objects as Promise rejection reasons",name:"twitter:image:alt"})})]})}function p(e={}){let{wrapper:r}={...(0,o.R)(),...e.components};return r?(0,t.jsx)(r,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}function m(e,r){throw Error("Expected "+(r?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}},46742(e,r,n){n.d(r,{A:()=>i});var s=n(65723);n(22155);var t=n(70851),o=n(28226);function l({children:e,className:r,hidden:n}){return(0,s.jsx)("div",{role:"tabpanel",className:(0,t.A)("tabItem_eQ9s",r),hidden:n,children:e})}function i({children:e,className:r,value:n}){let{selectedValue:t,lazy:a}=(0,o.uc)(),c=n===t;return!c&&a?null:(0,s.jsx)(l,{className:r,hidden:!c,children:e})}},70503(e,r,n){n.d(r,{A:()=>h});var s=n(65723);n(22155);var t=n(70851),o=n(98838),l=n(28226),i=n(26309),a=n(29021);function c({className:e}){let{selectedValue:r,selectValue:n,tabValues:o,block:a}=(0,l.uc)(),u=[],{blockElementScrollPositionUntilNextRender:d}
1=(0,i.a_)(),h=e=>{let s=e.currentTarget,t=o[u.indexOf(s)].value;t!==r&&(d(s),n(t))},p=e=>{let r=null;switch(e.key){case"Enter":h(e);break;case"ArrowRight":{let n=u.indexOf(e.currentTarget)+1;r=u[n]??u[0];break}case"ArrowLeft":{let n=u.indexOf(e.currentTarget)-1;r=u[n]??u[u.length-1]}}r?.focus()};return(0,s.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,t.A)("tabs",{"tabs--block":a},e),children:o.map(({value:e,label:n,attributes:o})=>(0,s.jsx)("li",{role:"tab",tabIndex:r===e?0:-1,"aria-selected":r===e,ref:e=>{u.push(e)},onKeyDown:p,onClick:h,...o,className:(0,t.A)("tabs__item","tabItem_e1w9",o?.className,{"tabs__item--active":r===e}),children:n??e},e))})}function u({children:e}){return(0,s.jsx)("div",{className:"margin-top--md",children:e})}function d({className:e,children:r}){return(0,s.jsxs)("div",{className:(0,t.A)(o.G.tabs.container,"tabs-container","tabList_mVW_"),children:[(0,s.jsx)(c,{className:e}),(0,s.jsx)(u,{children:r})]})}function h(e){let r=(0,a.A)(),n=(0,l.OC)(e);return(0,s.jsx)(l.O_,{value:n,children:(0,s.jsx)(d,{className:e.className,children:(0,l.vT)(e.children)})},String(r))}},28226(e,r,n){n.d(r,{OC:()=>h,O_:()=>g,uc:()=>m,vT:()=>u});var s=n(65723),t=n(22155),o=n(62934),l=n(24127),i=n(12910),a=n(22399),c=n(6660);function u(e){return t.Children.toArray(e).filter(e=>"\n"!==e)}function d({value:e,tabValues:r}){return r.some(r=>r.value===e)}function h(e){let r,{defaultValue:n,queryString:s=!1,groupId:u}=e,h=function(e){let{values:r,children:n}=e;return(0,t.useMemo)(()=>{let e=r??t.Children.toArray(n).flatMap(e=>{if(!e)return[];if((0,t.isValidElement)(e)&&function(e){let{props:r}=e;return!!r&&"object"==typeof r&&"value"in r}(e))return[e];let r="string"==typeof e.type?e.type:e.type.name;throw Error(`Docusaurus error: Bad <Tabs> child <${r}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop. 2If you do not want to pass on a "value" prop to the direct children of <Tabs>, you can also pass an explicit <Tabs values={...}> prop.`)}).map(({props:{value:e,label:r,attributes:n,default:s}})=>({value:e,label:r,attributes:n,default:s})),s=(0,a.XI)(e,(e,r)=>e.value===r.value);if(s.length>0)throw Error(`Docusaurus error: Duplicate values "${s.map(e=>`'${e.value}'`).join(", ")}" found in <Tabs>. Every value needs to be unique.`);return e},[r,n])}(e),[p,m]=(0,t.useState)(()=>(function({defaultValue:e,tabValues:r}){if(0===r.length)throw Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(e){if(!d({value:e,tabValues:r}))throw Error(`Docusaurus error: The <Tabs> has a defaultValue "${e}" but none of its children has the corresponding value. Available values are: ${r.map(e=>e.value).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return e}let n=r.find(e=>e.default)??r[0];if(!n)throw Error("Unexpected error: 0 tabValues");return n.value})({defaultValue:n,tabValues:h})),[g,j]=function({queryString:e=!1,groupId:r}){let n=(0,o.W6)(),s=function({queryString:e=!1,groupId:r}){if("string"==typeof e)return e;if(!1===e)return null;if(!0===e&&!r)throw Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return r??null}({queryString:e,groupId:r});return[(0,i.aZ)(s),(0,t.useCallback)(e=>{if(!s)return;let r=new URLSearchParams(n.location.search);r.set(s,e),n.replace({...n.location,search:r.toString()})},[s,n])]}({queryString:s,groupId:u}),[f,x]=function({groupId:e}){let r=e?`docusaurus.tab.${e}`:null,[n,s]=(0,c.Dv)(r);return[n,(0,t.useCallback)(e=>{r&&s.set(e)},[r,s])]}({groupId:u}),w=d({value:r=g??f,tabValues:h})?r:null;return(0,l.A)(()=>{w&&m(w)},[w]),{selectedValue:p,selectValue:(0,t.useCallback)(e=>{if(!d({value:e,tabValues:h}))throw Error(`Can't select invalid tab value=${e}`);m(e),j(e),x(e)},[j,x,h]),tabValues:h,lazy:e.lazy??!1,block:e.block??!1}}let p=(0,t.createContext)(null);function m(){let e=t.useContext(p);if(!e)throw Error("useTabsContext() must be used within a Tabs component");return e}function g(e){return(0,s.jsx)(p.Provider,{value:e.value,children:e.children})}},7143(e,r,n){n.d(r,{R:()=>l,x:()=>i});var s=n(22155);let t={},o=s.createContext(t);function l(e){let r=s.useContext(o);return s.useMemo(function(){return"function"==typeof e?e(r):{...r,...e}},[r,e])}function i(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:l(e.components),s.createElement(o.Provider,{value:r},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.