diff --git a/Tests/PromiseTests.cs b/Tests/PromiseTests.cs index b160cc1..ecdf995 100644 --- a/Tests/PromiseTests.cs +++ b/Tests/PromiseTests.cs @@ -202,7 +202,7 @@ 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(onRejected: e => throw new Exception("This shouldn't happen")); promise.Resolve(5); } @@ -1472,5 +1472,65 @@ public void rejected_reject_callback_is_caught_by_chained_catch() Assert.Equal(expectedException, actualException); } + + [Fact] + public void rejected_catch_returning_resolved_promise_state_is_adopted() + { + var promise = new Promise(); + int expectedValue = 1; + int actualValue = 0; + + promise.Catch(err => Promise.Resolved(expectedValue)) + .Then(result => { actualValue = result; }); + + promise.Reject(new Exception()); + + Assert.Equal(expectedValue, actualValue); + } + + [Fact] + public void rejected_catch_returning_rejected_promise_state_is_adopted() + { + var promise = new Promise(); + int expectedValue = 1; + int actualValue = 0; + + promise.Catch(err => Promise.Rejected(new Exception())) + .Catch(err => actualValue = expectedValue); + + promise.Reject(new Exception()); + + Assert.Equal(expectedValue, actualValue); + } + + [Fact] + public void rejected_catch_returning_resolved_promise_state_is_adopted_nongeneric() + { + var promise = new Promise(); + int expectedValue = 1; + int actualValue = 0; + + promise.Catch(err => Promise.Resolved()) + .Then(() => { actualValue = expectedValue; }); + + promise.Reject(new Exception()); + + Assert.Equal(expectedValue, actualValue); + } + + [Fact] + public void rejected_catch_returning_rejected_promise_state_is_adopted_nongeneric() + { + var promise = new Promise(); + int expectedValue = 1; + int actualValue = 0; + + promise.Catch(err => Promise.Rejected(new Exception())) + .Catch(err => actualValue = expectedValue); + + promise.Reject(new Exception()); + + Assert.Equal(expectedValue, actualValue); + } } } diff --git a/src/Promise.cs b/src/Promise.cs index b9c21f0..0fae860 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 and adopt status of returned promise.. + /// + IPromise Catch(Func> rejectionHandler); + /// /// Add a resolved callback that chains a value promise (optionally converting to a different value type). /// @@ -602,6 +607,35 @@ public IPromise Catch(Func onRejected) return resultPromise; } + /// + /// Handle errors for the promise and adopt status of returned promise.. + /// + public IPromise Catch(Func> recoveryMethod) { + var resultPromise = new Promise(); + resultPromise.WithName(Name); + + Action resolveHandler = v => resultPromise.Resolve(v); + + Action rejectHandler = ex => + { + try { + recoveryMethod(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 b10c6b6..5812a4b 100644 --- a/src/Promise_NonGeneric.cs +++ b/src/Promise_NonGeneric.cs @@ -46,6 +46,11 @@ public interface IPromise /// IPromise Catch(Action onRejected); + /// + /// Handle errors for the promise and adopt status of returned promise.. + /// + IPromise Catch(Func onRejected); + /// /// Add a resolved callback that chains a value promise (optionally converting to a different value type). /// @@ -689,6 +694,32 @@ public IPromise Catch(Action onRejected) return resultPromise; } + public IPromise Catch(Func onRejected) { + var resultPromise = new Promise(); + resultPromise.WithName(Name); + + Action resolveHandler = () => resultPromise.Resolve(); + + Action rejectHandler = ex => + { + try { + onRejected(ex) + .Progress(progress => resultPromise.ReportProgress(progress)) + .Then(() => resultPromise.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). ///