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

Appearance settings

[no-floating-promises] Provide a configuration option or other method to mark a Promise-returning function as "safe" #4722

Copy link
Copy link
Closed
@ArcanoxDragon

Description

@ArcanoxDragon
Issue body actions

Repro

I have encountered some cases while cleaning up some old JS code for my company (and converting it to TS in the process) where I want to register a .then() action on a Promise that I know will never be rejected. I don't want to have to use void whatever().then(...) on every single instance where I am dealing with one of these promises, as they may be used very frequently and having to remember to put void before every single usage of a non-rejecting promise is tedious (and ugly). I still want the warning to appear for promises that could be rejected, however, in case somebody forgets to handle an actual situation where a rejection might occur.

One specific example is in an AJAX helper method I created that will normalize any AJAX request (be it from one of our APIs or from an MVC backend), show an error message if it failed for some reason, or resolve a promise if it was successful. Here is some simplified pseudocode that should convey the general idea:

function sendAjaxAsync<Result = string>(options): Promise<Result> {
	return new Promise<Result>(res => {
		makeRequestAndNormalizeResponse(options).then(response => {
			if (response.isSuccessful) {
				res(response.result);
			} else {
				showErrorMessage(response.errorMessage);
			}
		});
	});
}

let myButton = $("#myButton");
let myContainer = $("#myContainer");

myButton.on("click", () => sendAjaxAsync({ url: "/foo/bar/baz" }).then(html => myContainer.append(html)));

If the request succeeds, the HTML from the response will be appended to myContainer. If it fails for some reason, sendAjaxAsync will show an appropriate error message to the user, and the continuation will not run. There will be no runtime errors or rejections at all.

Another use case might be something like a wrapper around setTimeout where the returned Promise is absolutely guaranteed to never reject ever, and it wouldn't even make sense to consider the possibility of a rejection:

// never rejects
function doSomething(): Promise<void> {
	/* ... */
}

// never rejects
function waitFor(ms: number): Promise<void> {
	return new Promise(res => setTimeout(res, ms));
}

let myButton = $("#myButton");
let myMessage = $("#myMessage");

myButton.on("click", () => {
	doSomething()
		.then(() => myMessage.show())
		.then(() => waitFor(2000))
		.then(() => myMessage.hide());
});

I'm sure there are plenty of other similar cases out there as well.

I am proposing a configuration rule such as the following to tell the no-floating-promises rule that the Promise returned by certain functions will NEVER be rejected so that a simple single-callback .then() is enough for it to be treated as "not floating":

{
    "rules": {
        "@typescript-eslint/no-floating-promises": ["warn", {
            "ignoredFunctions": [
                "doSomething",
                "waitFor"
            ]
        }]
    }
}

There may be a more elegant and/or flexible way of specifying this option; the example above is just one possibility.

Expected Result

I am expecting that, with the above hypothetical configuration, the example code would not have any linter warnings whatsoever.

Actual Result

Because no-floating-promises currently assumes that every Promise might be rejected, and thus must have a rejection handler registered 100% of the time, the above example raises a linter warning:

image

Additional Info

Versions

package version
@typescript-eslint/eslint-plugin 5.16.0
@typescript-eslint/parser 5.16.0
TypeScript 4.6.2
ESLint 8.10.0
node 16.12.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancement: plugin rule optionNew rule option for an existing eslint-plugin ruleNew rule option for an existing eslint-plugin rulepackage: eslint-pluginIssues related to @typescript-eslint/eslint-pluginIssues related to @typescript-eslint/eslint-pluginwontfixThis will not be worked onThis will not be worked on

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.