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.7KB

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