/// <summary> /// Executes the <param name="method"></param> with exception handling. /// </summary> /// <typeparam name="TResult">The type of the result.</typeparam> /// <param name="method">The method.</param> /// <returns>The object of type TResult.</returns> private static async Task <TResult> ExecuteWithExceptionHandlingAsync <TResult>(Func <Task <TResult> > method) { try { return(await method()); } catch (WebException ex) { using (var streamReader = new StreamReader(ex.Response.GetResponseStream())) { var response = streamReader.ReadToEnd(); // Deserializes to exception RetailProxyException crtException = null; if (DefaultExceptionHandlingBehavior.TryDeserializeFromJsonString(response, out crtException) && crtException != null) { throw crtException; } else { // If exception is not mapped to a commerce runtime exception, throws the local exception based on HTTP status code. CommunicationExceptionHelper.ThrowAsRetailProxyExceptionOnHttpStatuCode(ex, (int)((HttpWebResponse)ex.Response).StatusCode); throw ex; } } } }
/// <summary> /// Tries to throws a commerce exception, if the result could be serialized as a commerce exception; Proceeds silently, otherwise. /// </summary> /// <param name="result">The serialized return result.</param> private static void TryThrowAsCommerceException(string result) { if (!string.IsNullOrWhiteSpace(result)) { RetailProxyException crtException = null; if (DefaultExceptionHandlingBehavior.TryDeserializeFromJsonString(result, out crtException) && crtException != null) { throw crtException; } } }
/// <summary> /// Traverses and throws the commerce exception from the input exception hierarchy. /// </summary> /// <param name="exception">The exception to traverse.</param> public static void ThrowAsCommerceException(Exception exception) { Exception tempException = exception == null ? null : exception.InnerException; while (tempException != null && !string.IsNullOrWhiteSpace(tempException.Message)) { // Deserializes to exception RetailProxyException crtException = null; if (DefaultExceptionHandlingBehavior.TryDeserializeFromJsonString(tempException.Message, out crtException) && crtException != null) { throw crtException; } tempException = tempException.InnerException; } }
public static Collection <ResponseError> GetResponseErrorsFromException(Exception ex) { Collection <ResponseError> responseErrors = new Collection <ResponseError>(); if (ex != null) { Type exceptionType = ex.GetType(); if (exceptionType == typeof(DataValidationException) || exceptionType == typeof(CartValidationException)) { // Convert the validation results in the exception to response errors. // Convert the exception to response error. DataValidationException serverException = (DataValidationException)ex; responseErrors = CreateResponseErrorsFromFailures(serverException.ValidationResults, failure => new ResponseError(failure.ErrorResourceId, failure.LocalizedMessage)); responseErrors.Add(new ResponseError(serverException.ErrorResourceId, serverException.LocalizedMessage)); } else if (exceptionType == typeof(PaymentException)) { // Convert the payment SDK errors in the exception to response errors. // Convert the exception to response error. PaymentException serverException = ex as PaymentException; responseErrors = CreateResponseErrorsFromFailures(serverException.PaymentSdkErrors, error => new ResponseError(error.Code, error.Message)); responseErrors.Add(new ResponseError(serverException.ErrorResourceId, serverException.LocalizedMessage)); } else if (typeof(RetailProxyException).IsAssignableFrom(exceptionType)) { // Convert the exception to response error. RetailProxyException serverException = (RetailProxyException)ex; responseErrors.Add(new ResponseError(serverException.ErrorResourceId, serverException.LocalizedMessage)); } } if (!responseErrors.Any()) { responseErrors.Add(new ResponseError(Utilities.GenericErrorMessage, "Sorry something went wrong, we cannot process your request at this time. Please try again later.")); } return(responseErrors); }
/// <summary> /// Executes an action with the proper error handling logic. /// </summary> /// <typeparam name="T">The return type.</typeparam> /// <param name="action">The action to be performed.</param> /// <returns>The returned value from the action.</returns> private static Task <T> Execute <T>(Func <T> action) { return(Task.Run(() => { try { return action(); } catch (Exception ex) { string exceptionResponse = ex.SerializeToCommerceException(); RetailProxyException crtException = null; if (DefaultExceptionHandlingBehavior.TryDeserializeFromJsonString(exceptionResponse, out crtException) && crtException != null) { throw crtException; } throw new RetailProxyException(string.Format("Unexpected exception payload {0}.", exceptionResponse)); } })); }
/// <summary> /// Tries to deserialize an JSON string into a retail proxy exception, and suppresses any exceptions, if any. /// </summary> /// <param name="source">The JSON string.</param> /// <param name="exception">The retail proxy exception instance.</param> /// <returns>True, if the exception could be deserialized from the input; False, otherwise.</returns> internal static bool TryDeserializeFromJsonString(string source, out RetailProxyException exception) { ThrowIf.Null(source, "source"); exception = default(RetailProxyException); try { // Deserializes to a CommerceError object. CommerceError error = JsonConvert.DeserializeObject <CommerceError>( source, DefaultJsonSerializerSettings.Value); // Cannot deserialize the input to a CommerceError. if (error == null || string.IsNullOrWhiteSpace(error.TypeName) || error.Exception == null) { return(false); } // Then, based on the type of the exception, deserializes to the actual exception. string typeName = error.TypeName.Replace(CommerceExceptionTypeName, RetailProxyExceptionTypeName); exception = JsonConvert.DeserializeObject( error.Exception, KnownCommerceExceptionTypes.Value[typeName], DefaultJsonSerializerSettings.Value) as RetailProxyException; return(true); } catch { return(false); } }
/// <summary> /// Called when an exception is thrown. /// </summary> /// <param name="filterContext">The filter context.</param> protected override void OnException(ExceptionContext filterContext) { if (filterContext == null) { throw new ArgumentNullException("filterContext"); } base.OnException(filterContext); Exception currentException = null; if (filterContext.Exception as AggregateException != null) { currentException = filterContext.Exception.InnerException; } else { currentException = filterContext.Exception; } if (currentException as UserAuthorizationException != null || currentException as UserAuthenticationException != null || currentException as AuthenticationException != null) { ServiceUtilities.CleanUpOnSignOutOrAuthFailure(this.HttpContext); RetailProxyException retailProxyException = currentException as RetailProxyException; ResponseError responseError = new ResponseError() { ErrorCode = retailProxyException.ErrorResourceId, LocalizedErrorMessage = retailProxyException.LocalizedMessage, }; filterContext.Result = this.Json(responseError); filterContext.HttpContext.Response.StatusCode = 310; filterContext.HttpContext.Response.RedirectLocation = "/SignIn"; filterContext.ExceptionHandled = true; RetailLogger.Log.OnlineStoreForceSignOutOnAuthenticatedFlowError( filterContext.HttpContext.Response.StatusCode, filterContext.HttpContext.Response.RedirectLocation, filterContext.Exception, filterContext.Exception.InnerException); } else { if (currentException as CartValidationException != null) { CartValidationException cartValidationException = (CartValidationException)currentException; if (string.Equals(cartValidationException.ErrorResourceId, DataValidationErrors.Microsoft_Dynamics_Commerce_Runtime_CartNotFound.ToString(), StringComparison.OrdinalIgnoreCase)) { ServiceUtilities.ClearCartCookies(this.HttpContext); } } IEnumerable <ResponseError> responseErrors = Utilities.GetResponseErrorsFromException(currentException); filterContext.ExceptionHandled = true; filterContext.Result = this.Json(responseErrors); filterContext.HttpContext.Response.StatusCode = 400; RetailLogger.Log.OnlineStoreLogUnexpectedException( filterContext.RequestContext.HttpContext.Request.Url.AbsoluteUri, filterContext.Exception, filterContext.Exception.InnerException); } }