5
votes

I'm getting this error from TSLint and I'm trying to understand why it is complaining about.

I have a function which invokes another method which returns a promise but the first function does not return the promise because it just waits for it to finish and update an internal state.

I've simplified it to this function and just use Q() to simulate an invocation that returns a promise.

export function DoSomethingAsync(): void {
    Q().then(r => {
        console.log('test');
    }).catch(err => {
        log.error("wow");
    }).finally(() => {
        log.info("at finally")
    });
}

When I run tslint on my project now I'm getting the following error:

ERROR: C:/dev/local_cache_service.ts[31, 5]: Promises must be handled appropriately

If I remove the finally call tslint passes without errors.

export function DoSomethingAsync(): void {
    Q().then(r => {
        console.log('test');
    }).catch(err => {
        log.error("wow");
    });
}

When I create the same function on a seed typescript project this behavior does not reproduce...

2

2 Answers

6
votes

This is a complaint from the no-floating-promises rule. As per its description:

Creating a Promise and not storing or returning it may let other code run independently of its result. This can cause unexpected and/or non-deterministic behavior depending on external timing factors.

It’s typically better to return Promises from functions that start them, then handle them in calling code.

Use no-unused-expression in addition to this rule to reveal even more floating promises.

Specifically in your case, it's because you're running code in a .finally block after the .catch block. That's considered dangerous by the rule because if the code within the .finally throws an error, it'll be unhandled by the calling code.

The best thing for you to do would be to return the promise, so the function's return type is a Promise/Q instead of void.

Tip: you can run tslint -t stylish or tslint -t verbose to see rule names along with their complaints!

-1
votes

The solution was to add a call to .done() at the end of the promise call chain.

From what I understood done converts any unhandled exceptions to a regular unhandled exception.