Commerce Invoicing payment provider and ValidationException
I am using Umbraco 13.4.1 with Commerce.
Using the basic Invoicing PaymentProvider with a continue Url.
Generating the payment form using the html
using (await Html.BeginPaymentFormAsync(Model.Order))
If there are no problems this all works and I am sent onward the confirmation page.
But I have an event handler for ValidateOrderFinalize which may throw a ValidatationException such as
evt.Fail("Unable to send order");
When that exception is thrown I am getting a massive raw exception thrown onto the page. Lots of info in the logs which is fine but right now I don't know how to handle the error condition.
The Umbraco docs say only this:
This can then be captured in the front end to display a friendly error
message.
Yes ok, but how exactly??
The error log has this in it so I know that the correct exception is being thrown.
[17:13:42 WRN] Portal.Commerce.EventHandlers.OrderFinalisingValidationHandler: Unable to send order (7523f060-dfe0-495a-b9c6-0191bbd55fa0):Unable to post order: Invalid object name.
[17:13:53 ERR] Error processing Umbraco Commerce callback using StorefrontPaymentProviderDecorator`1 for order 1708-25230-RMWKR
Umbraco.Commerce.Common.Validation.ValidationException: Unable to send order
at Umbraco.Commerce.Infrastructure.Resiliency.PollyExecutionStrategyBase.ExecuteAsync[TResult](Func`2 operation, Func`2 verifySucceeded, CancellationToken cancellationToken)
at Umbraco.Commerce.Core.UmbracoCommerceUnitOfWorkProvider.ExecuteAsync[T](IUnitOfWorkOptions options, Func`3 action, CancellationToken cancellationToken)
at Umbraco.Commerce.Cms.Web.Controllers.UmbracoCommercePaymentController.Callback(IPaymentProvider paymentProvider, PaymentProviderContext ctx)
So how should I catch this exception to deal with it gracefully?
Lots of suggestions were about ensuring that a relevant Error content page was displayed, whereas my problem was simpler - I just wanted to return to the original page where the problem started.
Finally worked out that .Net Core has a pipeline handler for Exceptions where I could trap the exception of the specific type I wanted.
And then I included this in the Services Collection.
// handle specific types of exceptions
builder.Services.AddExceptionHandler<ValidationExceptionHandler>();
And the handler discovers the referring address, adds a query value and then returns true to short-circuit the request pipeline.
public class ValidationExceptionHandler() : IExceptionHandler
{
public ValueTask<bool> TryHandleAsync(HttpContext httpContext, Exception exception, CancellationToken cancellationToken)
{
if (exception is ValidationException)
{
var foundReferrer = httpContext.Request.Headers.Referer.ToString();
if (!string.IsNullOrEmpty(foundReferrer))
{
var referrerPath = new UriBuilder(foundReferrer).Path;
httpContext.Response.Redirect(referrerPath + $"?ex={exception.Message}");
return ValueTask.FromResult(true);
}
}
return ValueTask.FromResult(false);
}
}
I can then read the error message from the query string and add it to the validationSummary of the target page
So now the handling works as I want and in quite a straightforward way too which is nice.
But this was so ridiculously hard to work out as there is absolutely no mention of how to handle Commerce validation errors anywhere in the documentation!
Commerce Invoicing payment provider and ValidationException
I am using Umbraco 13.4.1 with Commerce.
Using the basic Invoicing PaymentProvider with a continue Url.
Generating the payment form using the html
using (await Html.BeginPaymentFormAsync(Model.Order))
If there are no problems this all works and I am sent onward the confirmation page. But I have an event handler for
ValidateOrderFinalize
which may throw a ValidatationException such asevt.Fail("Unable to send order");
When that exception is thrown I am getting a massive raw exception thrown onto the page. Lots of info in the logs which is fine but right now I don't know how to handle the error condition.
The Umbraco docs say only this:
Yes ok, but how exactly??
The error log has this in it so I know that the correct exception is being thrown.
So how should I catch this exception to deal with it gracefully?
All suggestions welcomed.
After a few days of struggle I have arrived at a solution.
I investigated several other possible solutions, including some fairly complicated ones such as https://dev.to/d_inventor/dynamic-error-pages-in-umbraco-10-19l3
Lots of suggestions were about ensuring that a relevant Error content page was displayed, whereas my problem was simpler - I just wanted to return to the original page where the problem started.
Finally worked out that .Net Core has a pipeline handler for Exceptions where I could trap the exception of the specific type I wanted. And then I included this in the Services Collection.
And the handler discovers the referring address, adds a query value and then returns true to short-circuit the request pipeline.
I can then read the error message from the query string and add it to the validationSummary of the target page
So now the handling works as I want and in quite a straightforward way too which is nice.
But this was so ridiculously hard to work out as there is absolutely no mention of how to handle Commerce validation errors anywhere in the documentation!
Anyway, I do hope this helps someone else.
is working on a reply...