no-floating-promises
Require Promise-like statements to be handled appropriately.
Extending"plugin:@typescript-eslint/recommended-type-checked" in anESLint configuration enables this rule.
Some problems reported by this rule are manually fixable by editorsuggestions.
This rule requirestype information to run, which comes with performance tradeoffs.
A "floating" Promise is one that is created without any code set up to handle any errors it might throw.Floating Promises can cause several issues, such as improperly sequenced operations, ignored Promise rejections, and more.
This rule will report Promise-valued statements that are not treated in one of the following ways:
- Calling its
.then()with two arguments - Calling its
.catch()with one argument awaiting itreturning itvoiding it
This rule also reports when an Array containing Promises is created and not properly handled. The main way to resolve this is by using one of the Promise concurrency methods to create a single Promise, then handling that according to the procedure above. These methods include:
Promise.all()Promise.allSettled()Promise.any()Promise.race()
no-floating-promises only detects apparently unhandled Promisestatements.Seeno-misused-promises for detecting code that provides Promises tological locations such as if statements.
SeeUsing promises (error handling) on MDN for a detailed writeup on Promise error-handling.
- Flat Config
- Legacy Config
exportdefault tseslint.config({
rules:{
"@typescript-eslint/no-floating-promises":"error"
}
});
module.exports={
"rules":{
"@typescript-eslint/no-floating-promises":"error"
}
};
Try this rule in the playground ↗
Examples
- ❌ Incorrect
- ✅ Correct
const promise=newPromise((resolve, reject)=>resolve('value'));
promise;
asyncfunctionreturnsPromise(){
return'value';
}
returnsPromise().then(()=>{});
Promise.reject('value').catch();
Promise.reject('value').finally();
[1,2,3].map(async x=> x+1);
Open in Playgroundconst promise=newPromise((resolve, reject)=>resolve('value'));
await promise;
asyncfunctionreturnsPromise(){
return'value';
}
voidreturnsPromise();
returnsPromise().then(
()=>{},
()=>{},
);
Promise.reject('value').catch(()=>{});
awaitPromise.reject('value').finally(()=>{});
awaitPromise.all([1,2,3].map(async x=> x+1));
Open in PlaygroundOptions
This rule accepts the following options:
typeOptions=[
{
/** Type specifiers of functions whose calls are safe to float. */
allowForKnownSafeCalls?:(
|{
from:'file';
name:string|string[];
path?:string;
}
|{
from:'lib';
name:string|string[];
}
|{
from:'package';
name:string|string[];
package:string;
}
|string
)[];
/** Type specifiers that are known to be safe to float. */
allowForKnownSafePromises?:(
|{
from:'file';
name:string|string[];
path?:string;
}
|{
from:'lib';
name:string|string[];
}
|{
from:'package';
name:string|string[];
package:string;
}
|string
)[];
/** Whether to check all "Thenable"s, not just the built-in Promise type. */
checkThenables?:boolean;
/** Whether to ignore async IIFEs (Immediately Invoked Function Expressions). */
ignoreIIFE?:boolean;
/** Whether to ignore `void` expressions. */
ignoreVoid?:boolean;
},
];
const defaultOptions: Options=[
{
allowForKnownSafeCalls:[],
allowForKnownSafePromises:[],
checkThenables:false,
ignoreIIFE:false,
ignoreVoid:true,
},
];
checkThenables
Whether to check all "Thenable"s, not just the built-in Promise type. Default:false.
A"Thenable" value is an object which has athen method, such as aPromise.Other Thenables include TypeScript's built-inPromiseLike interface and any custom object that happens to have a.then().
ThecheckThenables option triggersno-floating-promises to also consider all values that satisfy the Thenable shape (a.then() method that takes two callback parameters), not just Promises.This can be useful if your code works with olderPromise polyfills instead of the nativePromise class.
- ❌ Incorrect
- ✅ Correct
declarefunctioncreatePromiseLike(): PromiseLike<string>;
createPromiseLike();
interfaceMyThenable{
then(onFulfilled:()=>void,onRejected:()=>void): MyThenable;
}
declarefunctioncreateMyThenable(): MyThenable;
createMyThenable();
Open in PlaygrounddeclarefunctioncreatePromiseLike(): PromiseLike<string>;
awaitcreatePromiseLike();
interfaceMyThenable{
then(onFulfilled:()=>void,onRejected:()=>void): MyThenable;
}
declarefunctioncreateMyThenable(): MyThenable;
awaitcreateMyThenable();
Open in PlaygroundignoreVoid
Whether to ignorevoid expressions. Default:true.
Placing thevoid operator in front of a Promise can be a convenient way to explicitly mark that Promise as intentionally not awaited.
Voiding a Promise doesn't handle it or change the runtime behavior.The outcome is just ignored, like disabling the rule with anESLint disable comment.Such Promise rejections will still be unhandled.
Examples ofcorrect code for this rule with{ ignoreVoid: true }:
asyncfunctionreturnsPromise(){
return'value';
}
voidreturnsPromise();
voidPromise.reject('value');
Open in PlaygroundWhen this option is set totrue, if you are usingno-void, you should turn on theallowAsStatement option.
ignoreIIFE
Whether to ignore async IIFEs (Immediately Invoked Function Expressions). Default:false.
Examples ofcorrect code for this rule with{ ignoreIIFE: true }:
await(asyncfunction(){
awaitres(1);
})();
(asyncfunction(){
awaitres(1);
})();
Open in PlaygroundallowForKnownSafePromises
Type specifiers that are known to be safe to float. Default:[].
For example, you may need to do this in the case of libraries whose APIs return Promises whose rejections are safely handled by the library.
This option takes the sharedTypeOrValueSpecifier format.
Examples of code for this rule with:
{
"allowForKnownSafePromises":[
{"from":"file","name":"SafePromise"},
{"from":"lib","name":"PromiseLike"},
{"from":"package","name":"Bar","package":"bar-lib"}
]
}
- ❌ Incorrect
- ✅ Correct
let promise:Promise<number>=Promise.resolve(2);
promise;
functionreturnsPromise():Promise<number>{
returnPromise.resolve(42);
}
returnsPromise();
Open in Playground// promises can be marked as safe by using branded types
typeSafePromise=Promise<number>&{ __linterBrands?:string};
let promise: SafePromise=Promise.resolve(2);
promise;
functionreturnsSafePromise(): SafePromise{
returnPromise.resolve(42);
}
returnsSafePromise();
Open in PlaygroundallowForKnownSafeCalls
Type specifiers of functions whose calls are safe to float. Default:[].
For example, you may need to do this in the case of libraries whose APIs may be called without handling the resultant Promises.
This option takes the sharedTypeOrValueSpecifier format.
Examples of code for this rule with:
{
"allowForKnownSafeCalls":[
{"from":"file","name":"safe","path":"input.ts"}
]
}
- ❌ Incorrect
- ✅ Correct
declarefunctionunsafe(...args:unknown[]):Promise<void>;
unsafe('...',()=>{});
Open in Playgrounddeclarefunctionsafe(...args:unknown[]):Promise<void>;
safe('...',()=>{});
Open in PlaygroundWhen Not To Use It
This rule can be difficult to enable on large existing projects that set up many floating Promises.Alternately, if you're not worried about crashes from floating or misused Promises -such as if you have global unhandled Promise handlers registered- then in some cases it may be safe to not use this rule.You might consider usingvoids and/orESLint disable comments for those specific situations instead of completely disabling this rule.
Related To
Further Reading
- "Using Promises" MDN documentation. Note especially the sections onPromise rejection events andComposition.
Type checked lint rules are more powerful than traditional lint rules, but also require configuringtype checked linting.
SeeTroubleshooting > Linting with Type Information > Performance if you experience performance degradations after enabling type checked rules.