Skip to content

Feature proposal: no-double-resolve. Warn against resolving a promise twice, or execution after resolve. #222

Closed
@mrthehud

Description

@mrthehud

Description

I've noticed some errors when reviewing PRs where a promise is resolved, but where execution flow can continue to a point where the promise is then rejected, or where continuing execution would cause some other error that should be avoided.

I've read through the rules available, but I don't think any of them would achieve the following:

Steps to Reproduce

For example, the following less than ideal code:

(async () => {
    const someOptionalCache = undefined;
    const value = await new Promise((resolve) => {
        if (!someOptionalCache) {
            resolve(null);
        }
        
        resolve(someOptionalCache.fetch("some-key");
    });
})()

should really cause at least a warning imo.

Expected behavior:
Open to discussion, but perhaps a warning should be issued to the effect of 'a promise should not be resolved multiple times'

Naturally, it's entirely possible to want to continue executing code in a promise after it's resolved, but I don't think resolving twice would make sense, nor rejecting after a resolve, nor resolving after rejecting.

Does anybody else have thoughts (for or against) on this?

An additional or alternative rule that feels more restrictive, and might want to be ignored in some instances but not others (though would still provide protection, and may be easier to implement) would be to disallow or warn against execution of any code after resolve or reject is called.

Again, any thoughts for or against?

Examples of better code

The above could instead be either:

(async () => {
    const someOptionalCache = undefined;
    const value = await new Promise((resolve) => {
        if (!someOptionalCache) {
            resolve(null);

            return;
        }
        
        resolve(someOptionalCache.fetch("some-key");
    });
})()

or alternatively:

(async () => {
    const someOptionalCache = undefined;
    const value = await new Promise((resolve) => {
        if (!someOptionalCache) {
            resolve(null);
        } else {
            resolve(someOptionalCache.fetch("some-key");
        }
    });
})()

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions