Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Enhancement: [prefer-promise-reject-errors] option to allow 'rethrow' of signal reasons or caught values #11095

Open
Labels
awaiting responseIssues waiting for a reply from the OP or another partyenhancement: plugin rule optionNew rule option for an existing eslint-plugin rulepackage: eslint-pluginIssues related to @typescript-eslint/eslint-plugin
@turbocrime

Description

@turbocrime

Before You File a Proposal Please Confirm You Have Done The Following...

My proposal is suitable for this project

  • I believe my proposal would be useful to the broader TypeScript community (meaning it is not a niche proposal).

Link to the rule's documentation

https://typescript-eslint.io/rules/prefer-promise-reject-errors/

Description

When performing more complex async operations, a developer may call thereject executor of aPromise to propagate anAbortSignal reason, a value obtained by acatch block, or the reason parameter of a.then(_, onrejected) or.catch() callback.

in this case, it's often desirable toreject with the exact reason, to accurately propagate failures without changing them.

but,prefer-promise-reject-errors may complain unless these values are consistently verified.

it makes sense that some users of this rule may want the rule to enforce checking, assertion, or wrapping of reasons here, but i think it's common and good practice in many cases to simply propagate reasons without modifying them.

the rule is also applied inconsistently, and a few examples are provided.

Fail

// the rule must be disabled D: this should be unnecessaryfunctionrejectOnSignal(signal:AbortSignal){returnnewPromise<never>((_,reject)=>{// eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors -- rethrowsignal.addEventListener('abort',()=>reject(signal.reason));});}
// the rule must be disabled D: this should be unnecessaryfunctionrerejectOnCatch(param:Promise<unknown>){returnnewPromise<never>((_,reject)=>{// eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors -- rethrowparam.catch(e=>reject(e));});}

Pass

// yay the rule allows rethrow :D it's not necessary to disable itfunctionrejectOnSignal(signal:AbortSignal){returnnewPromise<never>((_,reject)=>{signal.addEventListener('abort',()=>reject(signal.reason));});}
// yay the rule allows rethrow :D it's not necessary to disable itfunctionrerejectOnCatch(param:Promise<unknown>){returnnewPromise<never>((_,reject)=>{param.catch(e=>reject(e));});}

Additional Info

the signal example is surprisingly common - an event listener is the most certain and reliable way to immediately react to signal activation.

the promise catch/rethrow is even more contrived, and debatable, but it makes sense to me that it should be possible to propagate a 'caught' value with no intervention.

inconsistent application: things that are presently permitted, but seem to violate the rule

rethrow behavior may be achieved a couple other ways, which the rule doesn't complain about, but i think that's a problem (the rule is inconsistent) rather than an acceptable workaround.

for example, this is permitted without complaint, but it appears to mostly be a failure to understand thereject ofPromise.withResolvers as a promise executor.

functionrejectOnSignal(signal:AbortSignal){const{ promise, reject}=Promise.withResolvers<never>();signal.addEventListener('abort',()=>reject(signal.reason));returnpromise;}

this triggers no complaints. it's kind of strange and i would also consider failure to detect this a lower priority, like the handler assignment. notably, this technique was the only way to obtain promise executor callbacks outside of the promise executor scope, beforePromise.withResolvers became available.

exportfunctionrejectOnSignal(signal:AbortSignal){letrejectExecutor;constpromise=newPromise<never>((_,reject)=>{rejectExecutor=reject;});signal.addEventListener('abort',()=>rejectExecutor(signal.reason));returnpromise;}

this next example is incorrect for a few reasons (the signal itself becomes the propagated value, this may clobber existing handlers), this is permitted without complaint. this appears mostly to be a failure to understand that assigningreject to an event handler attribute will result in a call toreject.

functionrejectOnSignal(signal:AbortSignal){returnnewPromise<never>((_,reject)=>{signal.onabort=reject;});}

Metadata

Metadata

Assignees

No one assigned

    Labels

    awaiting responseIssues waiting for a reply from the OP or another partyenhancement: plugin rule optionNew rule option for an existing eslint-plugin rulepackage: eslint-pluginIssues related to @typescript-eslint/eslint-plugin

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions


      [8]ページ先頭

      ©2009-2025 Movatter.jp