/// <summary> /// Formats an error with the stack trace included. /// </summary> /// <param name="error"></param> /// <returns></returns> public static string FormatMessageWithStackTrace(this HttpError error) { if (!error.ContainsKey("ExceptionMessage") || !error.ContainsKey("ExceptionType") || !error.ContainsKey("StackTrace")) { return(error.Message); } return(String.Format("[{0}] {1}\r\nStack Trace:\r\n{2}{3}", error["ExceptionType"], error["ExceptionMessage"], error["StackTrace"], Environment.NewLine)); }
public void ExceptionConstructorWithoutDetail_AddsCorrectDictionaryItems() { HttpError error = new HttpError(new ArgumentException("error", new Exception()), false); Assert.Contains(new KeyValuePair<string, object>("Message", "An error has occurred."), error); Assert.False(error.ContainsKey("ExceptionMessage")); Assert.False(error.ContainsKey("ExceptionType")); Assert.False(error.ContainsKey("StackTrace")); Assert.False(error.ContainsKey("InnerException")); }
public void HttpErrors_UseCaseInsensitiveComparer(HttpError httpError) { var lowercaseKey = "abcd"; var uppercaseKey = "ABCD"; httpError[lowercaseKey] = "error"; Assert.True(httpError.ContainsKey(lowercaseKey)); Assert.True(httpError.ContainsKey(uppercaseKey)); }
public void ExceptionConstructorWithoutDetail_AddsCorrectDictionaryItems() { HttpError error = new HttpError(new ArgumentException("error", new Exception()), false); Assert.Contains(new KeyValuePair <string, object>("Message", "An error has occurred."), error); Assert.False(error.ContainsKey("ExceptionMessage")); Assert.False(error.ContainsKey("ExceptionType")); Assert.False(error.ContainsKey("StackTrace")); Assert.False(error.ContainsKey("InnerException")); }
public static ModelStateDictionary ReconstructModelState(this HttpError httpError) { const string MODEL_STATE_KEY = "ModelState"; if (!httpError.ContainsKey(MODEL_STATE_KEY)) { return(null); } var reconstructedModelState = new ModelStateDictionary(); var modelStateErrors = (HttpError)httpError[MODEL_STATE_KEY]; foreach (var modelStateError in modelStateErrors) { var key = modelStateError.Key; var errorMessages = (string[])modelStateError.Value; foreach (var errorMessage in errorMessages) { reconstructedModelState.AddModelError(key, errorMessage); } } return(reconstructedModelState); }
public void ModelStateConstructorWithDetail_AddsCorrectDictionaryItems() { // Arrange ModelStateDictionary modelState = new ModelStateDictionary(); var provider = new EmptyModelMetadataProvider(); var metadata = provider.GetMetadataForProperty(typeof(string), nameof(string.Length)); modelState.AddModelError("[0].Name", "error1"); modelState.AddModelError("[0].Name", "error2"); modelState.AddModelError("[0].Address", "error"); modelState.AddModelError("[2].Name", new Exception("OH NO"), metadata); // Act HttpError error = new HttpError(modelState, true); // Assert HttpError modelStateError = error["ModelState"] as HttpError; Assert.Contains(new KeyValuePair <string, object>("Message", "The request is invalid."), error); Assert.Contains("error1", modelStateError["[0].Name"] as IEnumerable <string>); Assert.Contains("error2", modelStateError["[0].Name"] as IEnumerable <string>); Assert.Contains("error", modelStateError["[0].Address"] as IEnumerable <string>); Assert.True(modelStateError.ContainsKey("[2].Name")); Assert.Contains("OH NO", modelStateError["[2].Name"] as IEnumerable <string>); }
public void ConvertResponse_Returns_Error_Response_When_Formatter_Write_Throws_Immediately() { // Arrange Mock <JsonMediaTypeFormatter> formatterMock = new Mock <JsonMediaTypeFormatter>() { CallBase = true }; formatterMock.Setup(m => m.WriteToStreamAsync(It.IsAny <Type>(), It.IsAny <object>(), It.IsAny <Stream>(), It.IsAny <HttpContent>(), It.IsAny <TransportContext>())).Throws(new NotSupportedException("Expected error")); MemoryStream memoryStream = new MemoryStream(); Mock <HttpContextBase> contextMock = CreateMockHttpContextBaseForResponse(memoryStream); HttpResponseBase responseBase = contextMock.Object.Response; HttpRequestMessage request = new HttpRequestMessage(); request.Properties.Add(HttpPropertyKeys.IsLocalKey, new Lazy <bool>(() => true)); HttpResponseMessage response = new HttpResponseMessage() { RequestMessage = request }; response.Content = new ObjectContent <string>("hello", formatterMock.Object); // Act Task task = HttpControllerHandler.ConvertResponse(contextMock.Object, response, request); task.Wait(); // Assert preparation -- deserialize the HttpError response HttpError httpError = null; memoryStream.Seek(0L, SeekOrigin.Begin); using (StreamContent content = new StreamContent(memoryStream)) { content.Headers.ContentType = JsonMediaTypeFormatter.DefaultMediaType; httpError = content.ReadAsAsync <HttpError>().Result; } // Assert Assert.Equal <int>((int)HttpStatusCode.InternalServerError, responseBase.StatusCode); Assert.True(responseBase.Headers["Content-Type"].StartsWith(JsonMediaTypeFormatter.DefaultMediaType.MediaType)); Assert.Equal("An error has occurred.", httpError["Message"]); Assert.Equal("The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; charset=utf-8'.", httpError["ExceptionMessage"]); Assert.Equal(typeof(InvalidOperationException).FullName, httpError["ExceptionType"]); Assert.True(httpError.ContainsKey("StackTrace")); HttpError innerError = (httpError["InnerException"] as JObject).ToObject <HttpError>(); Assert.NotNull(innerError); Assert.Equal(typeof(NotSupportedException).FullName, innerError["ExceptionType"].ToString()); Assert.Equal("Expected error", innerError["ExceptionMessage"]); Assert.Contains("System.Net.Http.HttpContent.CopyToAsync", innerError["StackTrace"].ToString()); }
/// <summary> /// Occurs before the action method is invoked. /// </summary> /// <param name="actionContext">The action context.</param> public override void OnActionExecuting(HttpActionContext actionContext) { ModelStateDictionary modelState = actionContext.ModelState; IEntity valueArg = null; if (actionContext.ActionArguments.ContainsKey("value")) { valueArg = actionContext.ActionArguments["value"] as IEntity; } if (valueArg != null) { Type entityType = actionContext.ActionArguments["value"].GetType(); IgnoreModelErrorsAttribute ignoreModelErrorsAttribute = entityType.GetCustomAttributes(typeof(IgnoreModelErrorsAttribute), true).FirstOrDefault() as IgnoreModelErrorsAttribute; if (ignoreModelErrorsAttribute != null) { foreach (string key in ignoreModelErrorsAttribute.Keys) { IEnumerable <string> matchingKeys = modelState.Keys.Where(x => Regex.IsMatch(x, key)); foreach (string matchingKey in matchingKeys) { modelState[matchingKey].Errors.Clear(); } } } } if (!actionContext.ModelState.IsValid) { HttpError httpError = new HttpError(); foreach (var item in actionContext.ModelState) { foreach (ModelError error in item.Value.Errors) { if (!httpError.ContainsKey(item.Key)) { httpError.Add(item.Key, string.Empty); httpError[item.Key] += error.ErrorMessage; } else { httpError[item.Key] += Environment.NewLine + error.ErrorMessage; } } } actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, httpError); } }
/// <summary> /// Occurs before the action method is invoked. /// </summary> /// <param name="actionContext">The action context.</param> public override void OnActionExecuting( HttpActionContext actionContext ) { ModelStateDictionary modelState = actionContext.ModelState; IEntity valueArg = null; if ( actionContext.ActionArguments.ContainsKey( "value" ) ) { valueArg = actionContext.ActionArguments["value"] as IEntity; } if ( valueArg != null ) { Type entityType = actionContext.ActionArguments["value"].GetType(); IgnoreModelErrorsAttribute ignoreModelErrorsAttribute = entityType.GetCustomAttributes( typeof( IgnoreModelErrorsAttribute ), true ).FirstOrDefault() as IgnoreModelErrorsAttribute; if ( ignoreModelErrorsAttribute != null ) { foreach ( string key in ignoreModelErrorsAttribute.Keys ) { IEnumerable<string> matchingKeys = modelState.Keys.Where( x => Regex.IsMatch( x, key ) ); foreach ( string matchingKey in matchingKeys ) { modelState[matchingKey].Errors.Clear(); } } } } if ( !actionContext.ModelState.IsValid ) { HttpError httpError = new HttpError(); foreach ( var item in actionContext.ModelState ) { foreach ( ModelError error in item.Value.Errors ) { if ( !httpError.ContainsKey( item.Key ) ) { httpError.Add( item.Key, string.Empty ); httpError[item.Key] += error.ErrorMessage; } else { httpError[item.Key] += Environment.NewLine + error.ErrorMessage; } } } actionContext.Response = actionContext.Request.CreateErrorResponse( HttpStatusCode.BadRequest, httpError ); } }
public void ModelStateConstructorWithDetail_AddsCorrectDictionaryItems() { ModelStateDictionary modelState = new ModelStateDictionary(); modelState.AddModelError("[0].Name", "error1"); modelState.AddModelError("[0].Name", "error2"); modelState.AddModelError("[0].Address", "error"); modelState.AddModelError("[2].Name", new Exception("OH NO")); HttpError error = new HttpError(modelState, true); HttpError modelStateError = error["ModelState"] as HttpError; Assert.Contains(new KeyValuePair <string, object>("Message", "The request is invalid."), error); Assert.Contains("error1", modelStateError["[0].Name"] as IEnumerable <string>); Assert.Contains("error2", modelStateError["[0].Name"] as IEnumerable <string>); Assert.Contains("error", modelStateError["[0].Address"] as IEnumerable <string>); Assert.True(modelStateError.ContainsKey("[2].Name")); Assert.Contains("OH NO", modelStateError["[2].Name"] as IEnumerable <string>); }
private HttpResponseMessage Execute() { var httpResponseMessage = new HttpResponseMessage(); try { var negotiationResult = ContentNegotiator.Negotiate(typeof(HttpError), Request, Formatters); if (negotiationResult == null) { httpResponseMessage.StatusCode = HttpStatusCode.NotAcceptable; } else { var error = new HttpError("Validation Failed"); foreach (var err in _exception.ValidationErrors) { if (!error.ContainsKey(err.ItemName)) { error.Add(err.ItemName, new Collection <ApiError>()); } ((ICollection <ApiError>)error[err.ItemName]).Add(new ApiError { ErrorCode = err.ErrorCode, Message = err.ErrorMessage }); } httpResponseMessage.StatusCode = HttpStatusCode.BadRequest; httpResponseMessage.Content = new ObjectContent <HttpError>(error, negotiationResult.Formatter, negotiationResult.MediaType); } httpResponseMessage.RequestMessage = Request; } catch { httpResponseMessage.Dispose(); throw; } return(httpResponseMessage); }
private void HandleError(HttpResponseMessage response) { string message; if (response.StatusCode == HttpStatusCode.InternalServerError) { try { HttpError httpError = response.Content.ReadAsAsync <HttpError>().Result; string inner = httpError.ContainsKey("InnerException") ? httpError["InnerException"].ToString() : ""; message = httpError.ExceptionMessage + " " + httpError.Message + " " + httpError.StackTrace + " " + httpError.InnerException?.Message + inner; throw new Exception(message); } catch (Exception ex) { message = ex.Message; ErrorLogger.Log(message, ex); throw; } } else if (response.StatusCode == HttpStatusCode.BadRequest) { message = $"Status code: {response.StatusCode}."; } else if (response.StatusCode == HttpStatusCode.Gone) { message = $"Status code: {response.StatusCode}."; } else { message = response.Content.ReadAsStringAsync().Result; } Debug.WriteLine(message); var exception = new WebException(message); ErrorLogger.Log("ERROR IN HTTP REQUEST", exception); throw exception; }
private string ResolveMessage(HttpActionExecutedContext actionExecutedContext) { string reasonPhrase = actionExecutedContext.Response.ReasonPhrase; ObjectContent <HttpError> objectContent = actionExecutedContext.Response.Content as ObjectContent <HttpError>; if (objectContent == null) { return(reasonPhrase); } HttpError httpError = objectContent.Value as HttpError; if (httpError == null || !httpError.ContainsKey("Message")) { return(reasonPhrase); } string str = httpError["Message"] as string; return(string.IsNullOrWhiteSpace(str) ? reasonPhrase : str); }
public static string GetAllMessages(this HttpError error, bool includeStackTrace = false) { var builder = new StringBuilder(); HttpError current = error; while (current != null) { string message = includeStackTrace ? current.FormatMessageWithStackTrace() : current.Message; builder.Append(message); if (current.ContainsKey("InnerException")) { builder.Append(" --> "); current = current["InnerException"] as HttpError; } else { current = null; } } return(builder.ToString()); }
public void HttpErrors_UseCaseInsensitiveComparer(HttpError httpError) { var lowercaseKey = "abcd"; var uppercaseKey = "ABCD"; httpError[lowercaseKey] = "error"; Assert.True(httpError.ContainsKey(lowercaseKey)); Assert.True(httpError.ContainsKey(uppercaseKey)); }
public static bool HasValidationErrors(this HttpError error) { return(error.ContainsKey(ValidationErrorsFieldName)); }
private HttpResponseMessage BuildApiResponse(HttpRequestMessage request, HttpResponseMessage response) { object content; List <string> modelStateErrors = new List <string>(); if (response.TryGetContentValue(out content) && !response.IsSuccessStatusCode) { HttpError httpError = content as HttpError; if (httpError != null) { content = null; if (httpError.ModelState != null) { var httpErrorObject = response.Content.ReadAsStringAsync().Result; var anonymousErrorObject = new { message = "", ModelState = new Dictionary <string, string[]>() }; var deserializedErrorObject = JsonConvert.DeserializeAnonymousType(httpErrorObject, anonymousErrorObject); var modelStateValues = deserializedErrorObject.ModelState.Select(kvp => string.Join(". ", kvp.Value)); var stateValues = modelStateValues as string[] ?? modelStateValues.ToArray(); for (var i = 0; i < stateValues.Count(); i++) { modelStateErrors.Add(stateValues.ElementAt(i)); } } else if (httpError.ContainsKey("ExceptionType")) { if (httpError.ContainsValue("Saga.Gmd.WebApiServices.Common.DatabaseException")) { modelStateErrors.Add((httpError["ExceptionMessage"]?.ToString())); } } else if (httpError.Message.Length > 0 && string.IsNullOrEmpty(httpError.ExceptionMessage)) { modelStateErrors.Add(httpError.Message); } else if (!string.IsNullOrEmpty(httpError.Message)) { modelStateErrors.Add(httpError.ExceptionMessage); } } } string info = string.Empty; bool? IsAnyItemNull = null; //if (request.Method == HttpMethod.Get ) //{ switch (response.StatusCode) { case HttpStatusCode.OK: { object[] contents = content as object[]; if (contents != null) { foreach (var i in contents) { if (i != null) { if (i.GetType().Name == "NoAccessToMailingHistory") { var hasMessage = ((Models.JsonModels.NoAccessToMailingHistory)i).Message; if (hasMessage == null) { IsAnyItemNull = true; } } if (i.GetType().Name == "CustomerKeys") { var hasPartialResult = ((Models.JsonModels.CustomerKeys)i).Keys?.HasPartialResult; if (hasPartialResult == null) { IsAnyItemNull = true; } if (hasPartialResult != null && !hasPartialResult.Value) { var message = ((Models.JsonModels.CustomerKeys)i).Keys.Message; if (!string.IsNullOrEmpty(message)) { info = ErrorCodeInfo.RequestOkButResultNotFound; } } } else if (i.GetType().Name == "NoAccessToCusotmerKeys") { IsAnyItemNull = true; info = "No CustomerKeys found in the request"; } else if ((i.GetType().Name.ToString() == "HttpStatusCode")) { response.StatusCode = HttpStatusCode.NotFound; response.ReasonPhrase = "No Customer Found."; content = null; } else if (i is DatabaseException) { response.StatusCode = HttpStatusCode.NotFound; response.ReasonPhrase = "Invalid Data"; content = ((DatabaseException)i).Message; break; } } } } if (content == null) { info = ErrorCodeInfo.NoDataFound; } else if (content is string) { info = content.ToString(); content = null; } if (IsAnyItemNull.GetValueOrDefault()) { info = "One or more object contains " + "'null'" + ", because provided input didn't fetch any data."; } } break; case HttpStatusCode.BadRequest: info = ErrorCodeInfo.BadRequestInfo; break; case HttpStatusCode.Unauthorized: info = ErrorCodeInfo.UnAuthorizedInfo; modelStateErrors.Add(response.ReasonPhrase); break; case HttpStatusCode.InternalServerError: //info = ErrorCodeInfo.InternalServerErrorInfo; break; case HttpStatusCode.Forbidden: info = ErrorCodeInfo.ForbiddenInfo; break; default: if (!modelStateErrors.Any()) { modelStateErrors.Add(response.ReasonPhrase); } break; } //} var newResponse = request.CreateResponse(response.StatusCode, new ResponsePackage(content, response.StatusCode, response.ReasonPhrase, info, modelStateErrors)); foreach (var header in response.Headers) { newResponse.Headers.Add(header.Key, header.Value); } log.Info("RequestIdentification: " + _requestIdentification + " process ended."); return(newResponse); }
private HttpResponseMessage Execute() { var httpResponseMessage = new HttpResponseMessage(); try { var negotiationResult = ContentNegotiator.Negotiate(typeof(HttpError), Request, Formatters); if (negotiationResult == null) { httpResponseMessage.StatusCode = HttpStatusCode.NotAcceptable; } else { var error = new HttpError("Validation Failed"); foreach (var err in _exception.ValidationErrors) { if (!error.ContainsKey(err.ItemName)) { error.Add(err.ItemName, new Collection<ApiError>()); } ((ICollection<ApiError>)error[err.ItemName]).Add(new ApiError { ErrorCode = err.ErrorCode, Message = err.ErrorMessage }); } httpResponseMessage.StatusCode = HttpStatusCode.BadRequest; httpResponseMessage.Content = new ObjectContent<HttpError>(error, negotiationResult.Formatter, negotiationResult.MediaType); } httpResponseMessage.RequestMessage = Request; } catch { httpResponseMessage.Dispose(); throw; } return httpResponseMessage; }