PageRenderTime 42ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/Raven.Database/Server/WebApi/Filters/RavenExceptionFilterAttribute.cs

https://github.com/nwendel/ravendb
C# | 156 lines | 129 code | 20 blank | 7 comment | 4 complexity | bb247c4c30a180d951dbb4693ecc8eb9 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, BSD-3-Clause, CC-BY-SA-3.0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net;
  5. using System.Net.Http;
  6. using System.Web.Http.Filters;
  7. using Jint.Runtime;
  8. using Raven.Abstractions.Connection;
  9. using Raven.Abstractions.Data;
  10. using Raven.Abstractions.Exceptions;
  11. using Raven.Json.Linq;
  12. namespace Raven.Database.Server.WebApi.Filters
  13. {
  14. public class RavenExceptionFilterAttribute : ExceptionFilterAttribute
  15. {
  16. private static readonly Dictionary<Type, Action<HttpActionExecutedContext, Exception>> handlers =
  17. new Dictionary<Type, Action<HttpActionExecutedContext, Exception>>
  18. {
  19. {typeof (BadRequestException), (ctx, e) => HandleBadRequest(ctx, e as BadRequestException)},
  20. {typeof (ConcurrencyException), (ctx, e) => HandleConcurrencyException(ctx, e as ConcurrencyException)},
  21. {typeof (JavaScriptException), (ctx, e) => HandleJintException(ctx, e as JavaScriptException)},
  22. {typeof (IndexDisabledException), (ctx, e) => HandleIndexDisabledException(ctx, e as IndexDisabledException)},
  23. {typeof (IndexDoesNotExistsException), (ctx, e) => HandleIndexDoesNotExistsException(ctx, e as IndexDoesNotExistsException)},
  24. };
  25. public override void OnException(HttpActionExecutedContext ctx)
  26. {
  27. var e = ctx.Exception;
  28. var exceptionType = e.GetType();
  29. try
  30. {
  31. if (handlers.ContainsKey(exceptionType))
  32. {
  33. handlers[exceptionType](ctx, e);
  34. return;
  35. }
  36. var baseType = handlers.Keys.FirstOrDefault(t => t.IsInstanceOfType(e));
  37. if (baseType != null)
  38. {
  39. handlers[baseType](ctx, e);
  40. return;
  41. }
  42. DefaultHandler(ctx, e);
  43. }
  44. catch (Exception)
  45. {
  46. //TODO: log
  47. //logger.ErrorException("Failed to properly handle error, further error handling is ignored", e);
  48. }
  49. }
  50. public static void SerializeError(HttpActionExecutedContext ctx, object error)
  51. {
  52. ctx.Response.Content = new JsonContent(RavenJObject.FromObject(error))
  53. .WithRequest(ctx.Request);
  54. }
  55. private static void DefaultHandler(HttpActionExecutedContext ctx, Exception e)
  56. {
  57. ctx.Response = new HttpResponseMessage
  58. {
  59. StatusCode = HttpStatusCode.InternalServerError,
  60. };
  61. SerializeError(ctx, new
  62. {
  63. //ExceptionType = e.GetType().AssemblyQualifiedName,
  64. Url = ctx.Request.RequestUri.PathAndQuery,
  65. Error = e.ToString(),
  66. });
  67. }
  68. private static void HandleBadRequest(HttpActionExecutedContext ctx, BadRequestException e)
  69. {
  70. ctx.Response = new HttpResponseMessage
  71. {
  72. StatusCode = HttpStatusCode.BadRequest,
  73. };
  74. SerializeError(ctx, new
  75. {
  76. Url = ctx.Request.RequestUri.PathAndQuery,
  77. e.Message,
  78. Error = e.Message
  79. });
  80. }
  81. private static void HandleConcurrencyException(HttpActionExecutedContext ctx, ConcurrencyException e)
  82. {
  83. ctx.Response = new HttpResponseMessage
  84. {
  85. StatusCode = HttpStatusCode.Conflict,
  86. };
  87. SerializeError(ctx, new
  88. {
  89. Url = ctx.Request.RequestUri.PathAndQuery,
  90. ActualETag = e.ActualETag ?? Etag.Empty,
  91. ExpectedETag = e.ExpectedETag ?? Etag.Empty,
  92. Error = e.Message
  93. });
  94. }
  95. private static void HandleJintException(HttpActionExecutedContext ctx, JavaScriptException e)
  96. {
  97. //while (e.InnerException is JintException)
  98. //{
  99. // e = (JintException)e.InnerException;
  100. //}
  101. ctx.Response = new HttpResponseMessage
  102. {
  103. StatusCode = HttpStatusCode.BadRequest,
  104. };
  105. SerializeError(ctx, new
  106. {
  107. Url = ctx.Request.RequestUri.PathAndQuery,
  108. Error = e.Message
  109. });
  110. }
  111. private static void HandleIndexDoesNotExistsException(HttpActionExecutedContext ctx, IndexDoesNotExistsException e)
  112. {
  113. ctx.Response = new HttpResponseMessage
  114. {
  115. StatusCode = HttpStatusCode.NotFound,
  116. };
  117. SerializeError(ctx, new
  118. {
  119. Url = ctx.Request.RequestUri.PathAndQuery,
  120. Error = e.Message
  121. });
  122. }
  123. private static void HandleIndexDisabledException(HttpActionExecutedContext ctx, IndexDisabledException e)
  124. {
  125. ctx.Response = new HttpResponseMessage
  126. {
  127. StatusCode = HttpStatusCode.ServiceUnavailable,
  128. };
  129. SerializeError(ctx, new
  130. {
  131. Url = ctx.Request.RequestUri.PathAndQuery,
  132. Error = e.Information == null ? e.Message : e.Information.GetErrorMessage(),
  133. });
  134. }
  135. }
  136. }