Skip to content

Enhancement: no-floating-promises shouldn't allow returning a variable containing an unawaited promise. Returning an unawaited promise directly is fine. #8068

@BrannJoly

Description

@BrannJoly

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/no-floating-promises/

Description

no-floating-promise considers returning an unawaited promise is always ok.
While this is fine when you return the promise directly (ie return f()), this can be an issue if there are some intermediary steps before returning. I just spent a few hours trying to fix such a bug !

For example consider the following pseudocode :

async createObject(id:string){ ..... }

async x(id:string){
    const a = createObject(id); // note the missing await
    await doSomethingWithObject(id); // will fail because the object doesn't exist yet
    return a; // return the unawaited Promise, eslint doesn't complain
}

if doSomethingWithObject logically depends on the promise being on the previous line being resolved, this is a bug and should be flagged as such by eslint!

if doSomethingWithObject doesn't depend on the previous line being resolved, then we can rearrange the code:

  async x(){
     await doSomethingWithObject(); //doesn't depend on anything, so can be moved to the first line
     return createObject(); // here, the missing await is ok as we are returning immediately
     // the caller will be responsible for handling the promise properly
  }

Fail

async f(){ ..... }

async x(){
    const a = f();
    g();
    return a; // mishandled promise. Cannot return a variable containing an unawaited promise. 
    // await it, or return it directly ( ie. return f() ) 
}

Pass

async f(){ ..... }

async x(){
    g();
    return f(); // g doesn't need to be executed after f, move g() before f() and return f() directly

or 

async f(){ ..... }

async x(){
    const a = await f(); // g is supposed to be executed after f, add the missing await
    g(); 
    return a; 
}

Additional Info

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    duplicateThis issue or pull request already existsenhancement: 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