The next generation of the Teknik Services. Written in ASP.NET. https://www.teknik.io/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ErrorController.cs 7.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net.Mail;
  5. using System.Text;
  6. using Teknik.Areas.Error.ViewModels;
  7. using Teknik.Controllers;
  8. using Teknik.Filters;
  9. using Teknik.Utilities;
  10. using Teknik.Attributes;
  11. using Microsoft.AspNetCore.Mvc;
  12. using Microsoft.AspNetCore.Authorization;
  13. using Microsoft.Extensions.Logging;
  14. using Teknik.Configuration;
  15. using Microsoft.AspNetCore.Hosting;
  16. using Microsoft.AspNetCore.Http;
  17. using Microsoft.AspNetCore.Http.Extensions;
  18. using Microsoft.AspNetCore.Diagnostics;
  19. using Teknik.Data;
  20. using Teknik.Logging;
  21. namespace Teknik.Areas.Error.Controllers
  22. {
  23. [Authorize]
  24. [Area("Error")]
  25. public class ErrorController : DefaultController
  26. {
  27. public ErrorController(ILogger<Logger> logger, Config config, TeknikEntities dbContext) : base(logger, config, dbContext) { }
  28. [AllowAnonymous]
  29. [TrackPageView]
  30. public IActionResult HttpError(int statusCode)
  31. {
  32. switch (statusCode)
  33. {
  34. case 401:
  35. return Http401();
  36. case 403:
  37. return Http403();
  38. case 404:
  39. return Http404();
  40. default:
  41. return HttpGeneral(statusCode);
  42. }
  43. }
  44. [AllowAnonymous]
  45. [TrackPageView]
  46. public IActionResult HttpGeneral(int statusCode)
  47. {
  48. ViewBag.Title = statusCode;
  49. LogError(LogLevel.Error, "HTTP Error Code: " + statusCode);
  50. ErrorViewModel model = new ErrorViewModel();
  51. model.StatusCode = statusCode;
  52. return GenerateActionResult(CreateErrorObj("Http", statusCode, "Invalid HTTP Response"), View("~/Areas/Error/Views/Error/HttpGeneral.cshtml", model));
  53. }
  54. [AllowAnonymous]
  55. [TrackPageView]
  56. public IActionResult Http401()
  57. {
  58. Response.StatusCode = StatusCodes.Status401Unauthorized;
  59. ViewBag.Title = "Unauthorized";
  60. ViewBag.Description = "Unauthorized";
  61. LogError(LogLevel.Error, "Unauthorized");
  62. ErrorViewModel model = new ErrorViewModel();
  63. model.StatusCode = StatusCodes.Status401Unauthorized;
  64. return GenerateActionResult(CreateErrorObj("Http", StatusCodes.Status401Unauthorized, "Unauthorized"), View("~/Areas/Error/Views/Error/Http401.cshtml", model));
  65. }
  66. [AllowAnonymous]
  67. [TrackPageView]
  68. public IActionResult Http403()
  69. {
  70. Response.StatusCode = StatusCodes.Status403Forbidden;
  71. ViewBag.Title = "Access Denied";
  72. ViewBag.Description = "Access Denied";
  73. LogError(LogLevel.Error, "Access Denied");
  74. ErrorViewModel model = new ErrorViewModel();
  75. model.StatusCode = StatusCodes.Status403Forbidden;
  76. return GenerateActionResult(CreateErrorObj("Http", StatusCodes.Status403Forbidden, "Access Denied"), View("~/Areas/Error/Views/Error/Http403.cshtml", model));
  77. }
  78. [AllowAnonymous]
  79. [TrackPageView]
  80. public IActionResult Http404()
  81. {
  82. Response.StatusCode = StatusCodes.Status404NotFound;
  83. ViewBag.Title = "Not Found";
  84. ViewBag.Description = "Uh Oh, can't find it!";
  85. LogError(LogLevel.Warning, "Page Not Found");
  86. ErrorViewModel model = new ErrorViewModel();
  87. model.StatusCode = StatusCodes.Status404NotFound;
  88. return GenerateActionResult(CreateErrorObj("Http", StatusCodes.Status404NotFound, "Page Not Found"), View("~/Areas/Error/Views/Error/Http404.cshtml", model));
  89. }
  90. [AllowAnonymous]
  91. [TrackPageView]
  92. public IActionResult Http500(Exception exception)
  93. {
  94. try
  95. {
  96. if (HttpContext != null)
  97. {
  98. var ex = HttpContext.Features.Get<IExceptionHandlerFeature>();
  99. if (ex != null)
  100. {
  101. exception = ex.Error;
  102. }
  103. HttpContext.Session.Set("Exception", exception);
  104. }
  105. }
  106. catch
  107. { }
  108. Response.StatusCode = StatusCodes.Status500InternalServerError;
  109. ViewBag.Title = "Server Error";
  110. ViewBag.Description = "Something Borked";
  111. LogError(LogLevel.Error, "Server Error", exception);
  112. ErrorViewModel model = new ErrorViewModel();
  113. model.StatusCode = StatusCodes.Status500InternalServerError;
  114. model.Exception = exception;
  115. return GenerateActionResult(CreateErrorObj("Http", StatusCodes.Status500InternalServerError, exception.Message), View("~/Areas/Error/Views/Error/Http500.cshtml", model));
  116. }
  117. [HttpPost]
  118. [AllowAnonymous]
  119. [ValidateAntiForgeryToken]
  120. public IActionResult SubmitErrorReport(SubmitReportViewModel model)
  121. {
  122. try
  123. {
  124. string exceptionMsg = model.Exception;
  125. // Try to grab the actual exception that occured
  126. Exception ex = HttpContext.Session.Get<Exception>("Exception");
  127. if (ex != null)
  128. {
  129. exceptionMsg = string.Format(@"
  130. Exception: {0}
  131. Source: {1}
  132. Stack Trace:
  133. {2}
  134. ", ex.GetFullMessage(true), ex.Source, ex.StackTrace);
  135. }
  136. // Let's also email the message to support
  137. SmtpClient client = new SmtpClient();
  138. client.Host = _config.ContactConfig.EmailAccount.Host;
  139. client.Port = _config.ContactConfig.EmailAccount.Port;
  140. client.EnableSsl = _config.ContactConfig.EmailAccount.SSL;
  141. client.DeliveryMethod = SmtpDeliveryMethod.Network;
  142. client.UseDefaultCredentials = true;
  143. client.Credentials = new System.Net.NetworkCredential(_config.ContactConfig.EmailAccount.Username, _config.ContactConfig.EmailAccount.Password);
  144. client.Timeout = 5000;
  145. MailMessage mail = new MailMessage(new MailAddress(_config.NoReplyEmail, _config.NoReplyEmail), new MailAddress(_config.SupportEmail, "Teknik Support"));
  146. mail.Sender = new MailAddress(_config.ContactConfig.EmailAccount.EmailAddress);
  147. mail.Subject = "[Exception] Application Exception Occured";
  148. mail.Body = @"
  149. An exception has occured at: " + model.CurrentUrl + @"
  150. ----------------------------------------
  151. User Message:
  152. " + model.Message + @"
  153. ----------------------------------------
  154. " + exceptionMsg;
  155. mail.BodyEncoding = UTF8Encoding.UTF8;
  156. mail.DeliveryNotificationOptions = DeliveryNotificationOptions.Never;
  157. client.Send(mail);
  158. }
  159. catch (Exception ex)
  160. {
  161. return Json(new { error = "Error submitting report. Exception: " + ex.Message });
  162. }
  163. return Json(new { result = "true" });
  164. }
  165. private object CreateErrorObj(string type, int statusCode, string message)
  166. {
  167. return new { error = new { type = type, status = statusCode, message = message } };
  168. }
  169. private void LogError(LogLevel level, string message)
  170. {
  171. LogError(level, message, null);
  172. }
  173. private void LogError(LogLevel level, string message, Exception exception)
  174. {
  175. if (Request != null)
  176. {
  177. message += " | Url: " + Request.GetDisplayUrl();
  178. message += " | Referred Url: " + Request.Headers["Referer"].ToString();
  179. message += " | Method: " + Request.Method;
  180. message += " | User Agent: " + Request.Headers["User-Agent"].ToString();
  181. }
  182. _logger.Log(level, exception, message);
  183. }
  184. }
  185. }