From 1626852bf34e7942f12b507f194dc252f80a06c8 Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Tue, 7 May 2024 18:02:47 +0800 Subject: [PATCH] `throw-new-error`: Check all call expressions instead of just argument of `ThrowStatement` (#2332) --- docs/rules/throw-new-error.md | 10 +-- readme.md | 2 +- rules/throw-new-error.js | 11 +-- test/error-message.mjs | 1 + test/snapshots/error-message.mjs.md | 15 ++++ test/snapshots/error-message.mjs.snap | Bin 1325 -> 1367 bytes test/snapshots/throw-new-error.mjs.md | 113 +++++++++++++++++++----- test/snapshots/throw-new-error.mjs.snap | Bin 1015 -> 1238 bytes test/throw-new-error.mjs | 8 ++ 9 files changed, 123 insertions(+), 37 deletions(-) diff --git a/docs/rules/throw-new-error.md b/docs/rules/throw-new-error.md index 33e60fd883..72d2423d42 100644 --- a/docs/rules/throw-new-error.md +++ b/docs/rules/throw-new-error.md @@ -1,4 +1,4 @@ -# Require `new` when throwing an error +# Require `new` when creating an error 💼 This rule is enabled in the ✅ `recommended` [config](/~https://github.com/sindresorhus/eslint-plugin-unicorn#preset-configs-eslintconfigjs). @@ -12,7 +12,7 @@ While it's possible to create a new error without using the `new` keyword, it's ## Fail ```js -throw Error(); +const error = Error('unicorn'); ``` ```js @@ -20,13 +20,13 @@ throw TypeError('unicorn'); ``` ```js -throw lib.TypeError(); +throw lib.TypeError('unicorn'); ``` ## Pass ```js -throw new Error(); +const error = new Error('unicorn'); ``` ```js @@ -34,5 +34,5 @@ throw new TypeError('unicorn'); ``` ```js -throw new lib.TypeError(); +throw new lib.TypeError('unicorn'); ``` diff --git a/readme.md b/readme.md index 9cd69cf9a6..e25135c52b 100644 --- a/readme.md +++ b/readme.md @@ -223,7 +223,7 @@ If you don't use the preset, ensure you use the same `env` and `parserOptions` c | [switch-case-braces](docs/rules/switch-case-braces.md) | Enforce consistent brace style for `case` clauses. | ✅ | 🔧 | | | [template-indent](docs/rules/template-indent.md) | Fix whitespace-insensitive template indentation. | ✅ | 🔧 | | | [text-encoding-identifier-case](docs/rules/text-encoding-identifier-case.md) | Enforce consistent case for text encoding identifiers. | ✅ | 🔧 | 💡 | -| [throw-new-error](docs/rules/throw-new-error.md) | Require `new` when throwing an error. | ✅ | 🔧 | | +| [throw-new-error](docs/rules/throw-new-error.md) | Require `new` when creating an error. | ✅ | 🔧 | | diff --git a/rules/throw-new-error.js b/rules/throw-new-error.js index c8fb4476f3..2815f98691 100644 --- a/rules/throw-new-error.js +++ b/rules/throw-new-error.js @@ -3,7 +3,7 @@ const {switchCallExpressionToNewExpression} = require('./fix/index.js'); const messageId = 'throw-new-error'; const messages = { - [messageId]: 'Use `new` when throwing an error.', + [messageId]: 'Use `new` when creating an error.', }; const customError = /^(?:[A-Z][\da-z]*)*Error$/; @@ -11,13 +11,6 @@ const customError = /^(?:[A-Z][\da-z]*)*Error$/; /** @param {import('eslint').Rule.RuleContext} context */ const create = context => ({ CallExpression(node) { - if (!( - node.parent.type === 'ThrowStatement' - && node.parent.argument === node - )) { - return; - } - const {callee} = node; if (!( (callee.type === 'Identifier' && customError.test(callee.name)) @@ -45,7 +38,7 @@ module.exports = { meta: { type: 'suggestion', docs: { - description: 'Require `new` when throwing an error.', + description: 'Require `new` when creating an error.', }, fixable: 'code', messages, diff --git a/test/error-message.mjs b/test/error-message.mjs index 86a2d7f0d5..f4eb5ba101 100644 --- a/test/error-message.mjs +++ b/test/error-message.mjs @@ -69,6 +69,7 @@ test.snapshot({ 'throw new Error({foo: 0}.foo)', 'throw new Error(lineNumber=2)', 'const error = new RangeError;', + 'throw Object.assign(new Error(), {foo})', ], }); diff --git a/test/snapshots/error-message.mjs.md b/test/snapshots/error-message.mjs.md index 11e4c907ce..57b3116ac7 100644 --- a/test/snapshots/error-message.mjs.md +++ b/test/snapshots/error-message.mjs.md @@ -286,6 +286,21 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^ Pass a message to the \`RangeError\` constructor.␊ ` +## invalid(19): throw Object.assign(new Error(), {foo}) + +> Input + + `␊ + 1 | throw Object.assign(new Error(), {foo})␊ + ` + +> Error 1/1 + + `␊ + > 1 | throw Object.assign(new Error(), {foo})␊ + | ^^^^^^^^^^^ Pass a message to the \`Error\` constructor.␊ + ` + ## invalid(1): new AggregateError(errors) > Input diff --git a/test/snapshots/error-message.mjs.snap b/test/snapshots/error-message.mjs.snap index 60ff9c14e0869dbc2b78a0d1deecd54422039b15..03458966528d7893d1dd66de90e03bae740bf8dc 100644 GIT binary patch literal 1367 zcmV-d1*rN#RzV#6LlW zkU}D_O?^OW?3DMr57l_d#t2i41c|I^A(iW$|JXTMsC+5x2)48 zRPJr$)Zns#mOVx;4Gyz#cX#A&gV@V_p72;e#lFq#W#dVOl!_4*992aD%xdu?R9Qm7951BCCx zzJ8YW!n%a-@5M2EfSi;=44l*gz)g(|pW zR8@H|Exb>V(^?2mR}70HZEqx!{8iU~?Z+JT12z5!W`2Y+H5!O+Bccdo1bG&sL^Eor zlZpP0h(6DS&B^`%Zq1n*GpWuv)%=L+PIS6kQier7zC0J~d#j8vE}>IRN>HqxArXbn zF)d;|$|h=&h~-{A$FM;nX`gbOOd=nikS1iw$cv`BlKyg# z{->ezK78Id700UB@`bn(%h&q1RVeohMg1>(vG<$)EdjcZ2+7G;%k+hyCp}XRwPpXH z!~b_K!-{Ga6>+10w)x~xFc=6DCjp3dn;PN|4yT@g4h~6{O|4PB#HrnO%y^ zu2W`PQc`|bQOWOees5M!e|HJj8#a3ehXg)-ZclJaZU;=|R`w|KaIJ}tfy8Q)@zSE1A| zwxqOvw;M$$3_T=sYQQj-nd{Si3}u^u;&wdoS@*0V{QdQ*p&*gzpTb;^xO2Hi5$;SW;643jpfT+#DcLs4W@n;H?5+NMUt2e@-Uw5w;i#(i4_(Nn(j z$ZvPggr^8%A0np}o2Hr+r2zhc9@{T+Hcb}OePuv@&|}_g^AE;tLLd@*>&-6_u_=(+ z;r~#H|IRZau_`gKSz@pKOeV^0^ARNDl+;ftCRw>cI&ShA<3kpULuJL~p&mq=Dq)hB zZDgrnfrbrXo+2sVf{rPVnQWmM7!~zM+Efo0((E8-D;ALWyoQeMEwt<~&BEz@6iXXQ zA_JY&hm6T~QXeut=E>@i6;Xm~DuubFr9Nf+{VeqijH(y)X0YN+PPuF2q{jJuJD zji4SX-ye$z00000000BMnBQ(2MHI$e5JJiw7hF^bdXzvNht#!`I!PVHRfV`f;-8>G zNFkBe@z`_ofc#z|^aDq3*|5+HF)pMf{v9e4xY136x==XlSVo%OEk%Q*A-e7`xf zd*=JA({km}_rag=QmCGC#o*nZ_tBPIQE`0Ksvub_IjI&ph*;&vl)%Q{^_ z<-U!a8eF!}vPa0J!C@ZmZcW^65_?%J5*|ya*ms!SEEY+p5-oO^{TwaU{Z2oJhvR>V zJO{_J@3z5{3R(gj55(!2x`06WJ+EtF`yOGt*__*Uvzfv6Xz^lg-<{a5mFnaE0O9+v zr=O+WurA^IyKxK;kdtbNfsh7A%)`;_Bk68Z3iG$BhyUNqHJ^p}J5 zKMSSz;EUFYI8x<~FT|x-z0$v}Lv>gx>wnpez2Ee23D84CNY1`m<}U<2>6vnl)DXXaF!uzse?YQqqs8Aa6VPaJx(Ue2>`G*I zgEHHZlJdKbN`8;?d%b%8yGyv4i*r6+PFZ)6z#(Tn z6fiYgp-=ZIlx+fv+w;Wd{nM84_crE+f<)$rf@NM2lpQ?agtOOI zj@KPemBdBEGzBsu6qFZ8W-xo#C1ofmc0=G)#c~F`ttWe^h^c$ zS`P8>3KW~?NaH+YW6&6biH*dGSg@QWnq@r(w8cU{U+t01j>HYqdJ~RZQLO2iA-g~8 zu)ItlxrZ#>PU@6vl^nWdtV2IvEZ)IsgSIt2Uo;d&MvbWvF{xu}M0^0b07UooEYi4d z>mUZocOLrP{;BX3LF^;sv}V&(v!WEhKhOp6MZu=YV!E#k=nr~KneY9bahq_V{{`WD zn& 1 | throw Error()␊ - | ^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(2): throw (Error)() @@ -43,7 +43,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw (Error)()␊ - | ^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(3): throw lib.Error() @@ -64,7 +64,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw lib.Error()␊ - | ^^^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(4): throw lib.mod.Error() @@ -85,7 +85,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw lib.mod.Error()␊ - | ^^^^^^^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(5): throw lib[mod].Error() @@ -106,7 +106,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw lib[mod].Error()␊ - | ^^^^^^^^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(6): throw (lib.mod).Error() @@ -127,7 +127,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw (lib.mod).Error()␊ - | ^^^^^^^^^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^^^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(7): throw Error('foo') @@ -148,7 +148,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw Error('foo')␊ - | ^^^^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(8): throw CustomError('foo') @@ -169,7 +169,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw CustomError('foo')␊ - | ^^^^^^^^^^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^^^^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(9): throw FooBarBazError('foo') @@ -190,7 +190,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw FooBarBazError('foo')␊ - | ^^^^^^^^^^^^^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^^^^^^^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(10): throw ABCError('foo') @@ -211,7 +211,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw ABCError('foo')␊ - | ^^^^^^^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(11): throw Abc3Error('foo') @@ -232,7 +232,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw Abc3Error('foo')␊ - | ^^^^^^^^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(12): throw TypeError() @@ -253,7 +253,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw TypeError()␊ - | ^^^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(13): throw EvalError() @@ -274,7 +274,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw EvalError()␊ - | ^^^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(14): throw RangeError() @@ -295,7 +295,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw RangeError()␊ - | ^^^^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(15): throw ReferenceError() @@ -316,7 +316,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw ReferenceError()␊ - | ^^^^^^^^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(16): throw SyntaxError() @@ -337,7 +337,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw SyntaxError()␊ - | ^^^^^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(17): throw URIError() @@ -358,7 +358,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw URIError()␊ - | ^^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(18): throw (( URIError() )) @@ -379,7 +379,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw (( URIError() ))␊ - | ^^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(19): throw (( URIError ))() @@ -400,7 +400,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw (( URIError ))()␊ - | ^^^^^^^^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(20): throw getGlobalThis().Error() @@ -421,7 +421,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw getGlobalThis().Error()␊ - | ^^^^^^^^^^^^^^^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^^^^^^^^^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(21): throw utils.getGlobalThis().Error() @@ -442,7 +442,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw utils.getGlobalThis().Error()␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use \`new\` when creating an error.␊ ` ## invalid(22): throw (( getGlobalThis().Error ))() @@ -463,5 +463,74 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | throw (( getGlobalThis().Error ))()␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use \`new\` when throwing an error.␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use \`new\` when creating an error.␊ + ` + +## invalid(23): const error = Error() + +> Input + + `␊ + 1 | const error = Error()␊ + ` + +> Output + + `␊ + 1 | const error = new Error()␊ + ` + +> Error 1/1 + + `␊ + > 1 | const error = Error()␊ + | ^^^^^^^ Use \`new\` when creating an error.␊ + ` + +## invalid(24): throw Object.assign(Error(), {foo}) + +> Input + + `␊ + 1 | throw Object.assign(Error(), {foo})␊ + ` + +> Output + + `␊ + 1 | throw Object.assign(new Error(), {foo})␊ + ` + +> Error 1/1 + + `␊ + > 1 | throw Object.assign(Error(), {foo})␊ + | ^^^^^^^ Use \`new\` when creating an error.␊ + ` + +## invalid(25): new Promise((resolve, reject) => { reject(Error('message')); }); + +> Input + + `␊ + 1 | new Promise((resolve, reject) => {␊ + 2 | reject(Error('message'));␊ + 3 | });␊ + ` + +> Output + + `␊ + 1 | new Promise((resolve, reject) => {␊ + 2 | reject(new Error('message'));␊ + 3 | });␊ + ` + +> Error 1/1 + + `␊ + 1 | new Promise((resolve, reject) => {␊ + > 2 | reject(Error('message'));␊ + | ^^^^^^^^^^^^^^^^ Use \`new\` when creating an error.␊ + 3 | });␊ ` diff --git a/test/snapshots/throw-new-error.mjs.snap b/test/snapshots/throw-new-error.mjs.snap index 740e4683ae572914755cffcd32a09ef86aa71046..aa2b8ade04c70672ba986fdc3a834abce7a90778 100644 GIT binary patch literal 1238 zcmV;{1S$JLRzVR|A(1ezEyg;Mu*KOU1y>)4wGN4Q?TBm^~gbLj% z7*pAt
=zRGsmm9?)B{{rGIllVW8o7m^C@41WXB=}vVe82bH=g!Y_&-tHj%NOna z=vY`M{dwvAg%1{z z=fcH>4=;RFW6WVED5`PaZE>GJ4GxC!SXKwwBFF+>lyhplLL+-|2&|_}Ecp__zNAu21n6u)fK(3@fni&x5>`yj@TSRxl?0fn&|FK=tYv6?uhr1*7t_M$gcP28AibvGQRN88 z1^qJsl-H7orh;@ch4dLf8iaCwF4OmQ#~oCe|b6yXu^m$>UK)%%Z$|HVHAsjnO6fsW-w<}Pf=@v!)=9{)&urwX;7VOG>hjcyj3al_=$eRVb$t$ZIM+klS;|Pf7a2%0YOSTR>yvsu#wDq`5Q!c8jWG#(H`K+ZF%qeTJ z44>>Bo*f6V`$o&obbA3(3Y@9wNWf7BNR5NTPe2XTT4b}h261Ggu)FhA3+q#e_G6f@ z)KR4Fg7T_DN>L-GS0MipFy*8)qnW&qvOln_+>p#Z=lfVxpZ9&VtO76Tfynw`@(XsN z#US$FX3uV&V#jRq8nPt2Gj)|*rtv7B%M^n-<+8ik?X5ie_jvrRFIukuyzfPp;WlIq zCU6HRXiO-W>tJ(Fg-Lqps2+pcK2X&KHLz>VJag5l}Y=Sc3fwSD=|s5@bl4jA2>*x;*o@H=)a!Ptq3VDf5CwANng|G3kEubLUEhX*EP9wWmmJ^`i-~ah8sm*FR;er zFSEB@Ax_V^bB$K#-MMI%V_Psp#;4#YVCR~{qlnLn`}Z05q(w^R@<6krDJTo~5 z)-)Y-yB~`P00000000BE*j-Q4P#gwuh%qMId0`Y$IJ~(IbWji#6E#545HEf`+4X+@so@(cFwLpKd(P**XQie<()&; zX>j*CV7ql@xr|@NO5I}mVqATxNRdp#_#VQwMKKDc2*D8vB^gGR zeMoNti%1eMxoDn-G>Z|9W0yCS|-wPP|7*1cwIOS(T!K6HmDM}Eq2`vXW zokr%9Qdp>YUV+dvVAzj|_3%1L!Ra1cu_!_w%_>l^ORS9Du!<{()Kn<- zCX!lf`+?WgdzE0w46a$uQ)&y)FeRxeThPvf8Vl@*3he`z$FUGPE=P_ZJ#W=&ty;hI zl)C>NSwU$oK}kW<)DO1J1ud$f|6^O5Vy>Y83uw+1J|S=L~>BK;bi%=c#v zj#d#<90yj)l|?RB5MsdjU}jPIu_I zgrf>jjYGp%P{Xv6tQW6AOmR@y-P%xMJ%iCcg6kDIN@@m@Pb4WRjZ6m+{{l?0C~ee} z|D!k`7)I@qYe2~lJc%X;5r^x&-7;mzisWm^ly+C?EOVKn zBmG<^74&H?n~C1uimiX02cI0TY&km(+cz|CLl)rzra?hbLSZgL&8&<`cBxd)pzR1$ zRfD?maFxq=J~9@Egmz#%ekrxIj!0WYd4GU1Q})(0s?`5LX9v{v159Dx!#l7LpCrg3 lDP|1a9ne-$ci { + reject(Error('message')); + }); + `, ], });