Added Error Handling

This commit is contained in:
Charles Showalter 2022-05-11 12:04:56 -07:00
parent e57e87ad9e
commit 9b5964fc13
26 changed files with 161 additions and 4 deletions

View File

@ -0,0 +1,11 @@
using Microsoft.AspNetCore.Mvc;
namespace API.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class BaseApiController : ControllerBase
{
}
}

View File

@ -0,0 +1,47 @@
using API.Errors;
using Infrastructure.Data;
using Microsoft.AspNetCore.Mvc;
namespace API.Controllers
{
public class BuggyController : BaseApiController
{
private readonly StoreContext _context;
public BuggyController(StoreContext context)
{
_context = context;
}
[HttpGet("notfound")]
public ActionResult GetNotFoundRequest()
{
var thing = _context.Products.Find(42);
if (thing == null)
{
return NotFound(new ApiResponse(404));
}
return Ok();
}
[HttpGet("servererror")]
public ActionResult GetServerError()
{
var thing = _context.Products.Find(42);
var thingToReturn = thing.ToString();
return Ok();
}
[HttpGet("badrequest")]
public ActionResult GetBadRequest()
{
return BadRequest(new ApiResponse(400));
}
[HttpGet("badrequest/{id}")]
public ActionResult GetNotFoundRequest(int id)
{
return Ok();
}
}
}

View File

@ -0,0 +1,14 @@
using API.Errors;
using Microsoft.AspNetCore.Mvc;
namespace API.Controllers
{
[Route("errors/{code}")]
public class ErrorController : BaseApiController
{
public IActionResult Error(int code)
{
return new ObjectResult(new ApiResponse(code));
}
}
}

View File

@ -7,9 +7,7 @@ using AutoMapper;
namespace API.Controllers namespace API.Controllers
{ {
[ApiController] public class ProductsController : BaseApiController
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{ {
private readonly IGenericRepository<Product> _productsRepo; private readonly IGenericRepository<Product> _productsRepo;
private readonly IGenericRepository<ProductBrand> _productBrandRepo; private readonly IGenericRepository<ProductBrand> _productBrandRepo;

View File

@ -0,0 +1,12 @@
namespace API.Errors
{
public class ApiException : ApiResponse
{
public ApiException(int statusCode, string message = null, string details = null) : base(statusCode, message)
{
Details = details;
}
public string Details { get; set; }
}
}

31
API/Errors/ApiResponse.cs Normal file
View File

@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace API.Errors
{
public class ApiResponse
{
public ApiResponse(int statusCode, string message = null)
{
StatusCode = statusCode;
Message = message ?? GetDefaultMessageForStatusCode(statusCode);
}
public int StatusCode { get; set; }
public string Message { get; set; }
private string GetDefaultMessageForStatusCode(int statusCode)
{
return statusCode switch
{
400 => "A bad request, you have made",
401 => "Authorized, you are not",
404 => "Resource found, it was not",
500 => "Errors are the path to the dark side. Errors lead to anger. Anger leads to hate. Hate leads to career change",
_ => null
};
}
}
}

View File

@ -0,0 +1,39 @@
using System.Net;
using System.Text.Json;
using API.Errors;
namespace API.Middleware
{
public class ExceptionMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<ExceptionMiddleware> _logger;
private readonly IHostEnvironment _env;
public ExceptionMiddleware(RequestDelegate next, ILogger<ExceptionMiddleware> logger, IHostEnvironment env)
{
_env = env;
_logger = logger;
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
try
{
await _next(context);
}
catch (Exception ex)
{
_logger.LogError(ex, ex.Message);
context.Response.ContentType = "application/json";
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
var response = _env.IsDevelopment()
? new ApiException((int)HttpStatusCode.InternalServerError, ex.Message, ex.StackTrace.ToString())
: new ApiException((int)HttpStatusCode.InternalServerError);
var options = new JsonSerializerOptions{PropertyNamingPolicy = JsonNamingPolicy.CamelCase};
var json = JsonSerializer.Serialize(response, options);
await context.Response.WriteAsync(json);
}
}
}
}

View File

@ -1,4 +1,5 @@
using API.Helpers; using API.Helpers;
using API.Middleware;
using Core.Interfaces; using Core.Interfaces;
using Infrastructure.Data; using Infrastructure.Data;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
@ -33,16 +34,20 @@ namespace API
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{ {
app.UseMiddleware<ExceptionMiddleware>();
if (env.IsDevelopment()) if (env.IsDevelopment())
{ {
app.UseDeveloperExceptionPage();
app.UseSwagger(); app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "WebAPIv5 v1")); app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "WebAPIv5 v1"));
} }
app.UseStatusCodePagesWithReExecute("/errors/{0}");
app.UseHttpsRedirection(); app.UseHttpsRedirection();
app.UseRouting(); app.UseRouting();
app.UseStaticFiles();
app.UseAuthorization(); app.UseAuthorization();

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB