Skip to content

tap analog for catch #589

@Artazor

Description

@Artazor

What about .tapError() with the same signature as .catch (with filters) but the following semantics? (analog to #116)

var noError = {};
Promise.prototype.tapError = function() {
    var e = noError;
    var p = this.catch(function(reason){
        throw e = reason; 
    });
    return p.catch.apply(p,arguments).then(function(value){
        if (e === noError) {
            return value;
        } else {
            throw e;
        }
    })
}

Please understand the motivation (!)

It is motivated by the TypeScript usage (@spion you are welcome to comment)
When you write a catch handler only for logging purposes you never return and always throw, but type signature of resulting promise is completely vanished. e.g.

the problem

return Promise
    .resolve("MyString")
    .then(transform)
    .catch(TransformError, (e: TransformError) => {
        console.log("Transormation failed", e.tranformFailureReason);
        throw e;
    }).then ...   // Here we have Promise<void> instead of Promise<string>

failed attempt

return Promise
    .resolve("MyString")
    .then(transform)
    .catch(TransformError, (e: TransformError): string => {
        console.log("Transormation failed", e.tranformFailureReason);
        throw e;
    }).then ...   // Does not compile with TS1.4 - error TS2355

It fails with

error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement.

Technically this approach fails only because of microsoft/TypeScript#1613 and will work as soon as static flow analysis will be implemented inTypeScript. However I suppose that it is wrong to specify a return type for this handler. It is not intended to return.

ugly yet successfull

return Promise
    .resolve("MyString")
    .then(transform)
    .catch(TransformError, (e: TransformError): Promise<string> => {
        console.log("Transormation failed", e.tranformFailureReason);
        return Promise.reject<string>(e);
    }).then ...   // Here we have Promise<string> 

proposed

return Promise
    .resolve("MyString")
    .then(transform)
    .tapError(TransformError, (e: TransformError) => {
        console.log("Transormation failed", e.tranformFailureReason);
    }).then ...   // Here we have Promise<string> !!!

Does it sound reasonable?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions