diff --git a/Tests/PromiseTests.cs b/Tests/PromiseTests.cs index 7d0c3f6..f15e42e 100644 --- a/Tests/PromiseTests.cs +++ b/Tests/PromiseTests.cs @@ -202,7 +202,10 @@ public void error_handler_is_not_invoked_for_resolved_promised() { var promise = new Promise(); - promise.Catch(e => throw new Exception("This shouldn't happen")); + promise.Catch(e => { + throw new Exception("This shouldn't happen"); + return -1; + }); promise.Resolve(5); } @@ -759,7 +762,6 @@ public void can_chain_promise_and_convert_type_of_value() .Then(v => { Assert.Equal(chainedPromiseValue, v); - ++completed; }); @@ -1424,5 +1426,35 @@ public void rejected_reject_callback_is_caught_by_chained_catch() Assert.Equal(expectedException, actualException); } + + [Fact] + public void resolved_callback_is_caught_by_catch_returning_promise() { + var promise = new Promise(); + int excepectedValue = 1; + int actualValue = 0; + + promise.Catch(err => Promise.Resolved(-1)) + .Then(result => { actualValue = result; }) + .Catch(err => throw new Exception("Should not happend.")); + + promise.Resolve(1); + + Assert.Equal(excepectedValue, actualValue); + } + + [Fact] + public void rejected_callback_is_caught_by_catch_returning_promise() { + var promise = new Promise(); + int excepectedValue = -1; + int actualValue = 0; + + promise.Catch(err => Promise.Rejected(new Exception())) + .Then(result => throw new Exception("Should not happend.")) + .Catch(err => actualValue = -1); + + promise.Resolve(1); + + Assert.Equal(excepectedValue, actualValue); + } } } diff --git a/src/Promise.cs b/src/Promise.cs index 7647358..2b3c83b 100644 --- a/src/Promise.cs +++ b/src/Promise.cs @@ -51,6 +51,11 @@ public interface IPromise /// IPromise Catch(Func onRejected); + /// + /// Handle errors for the promise. + /// + IPromise Catch(Func> onRejected); + /// /// Add a resolved callback that chains a value promise (optionally converting to a different value type). /// @@ -580,6 +585,35 @@ public IPromise Catch(Func onRejected) return resultPromise; } + + /// + /// Handle errors for the promise. + /// + public IPromise Catch(Func> onRejected) { + var resultPromise = new Promise(); + resultPromise.WithName(Name); + + Action resolveHandler = v => resultPromise.Resolve(v); + + Action rejectHandler = ex => + { + try { + onRejected(ex) + .Progress(progress => resultPromise.ReportProgress(progress)) + .Then(resolve => resultPromise.Resolve(resolve)) + .Catch(reject => resultPromise.Reject(ex)); + } + catch (Exception cbEx) + { + resultPromise.Reject(cbEx); + } + }; + + ActionHandlers(resultPromise, resolveHandler, rejectHandler); + ProgressHandlers(resultPromise, v => resultPromise.ReportProgress(v)); + + return resultPromise; + } /// /// Add a resolved callback that chains a value promise (optionally converting to a different value type). diff --git a/src/Promise_NonGeneric.cs b/src/Promise_NonGeneric.cs index ae76308..22aa0e2 100644 --- a/src/Promise_NonGeneric.cs +++ b/src/Promise_NonGeneric.cs @@ -646,8 +646,6 @@ public IPromise WithName(string name) /// public IPromise Catch(Action onRejected) { -// Argument.NotNull(() => onRejected); - var resultPromise = new Promise(); resultPromise.WithName(Name);