Error messages returned from each error have differenct formats and this makes it hard for front developers to work with. We will see how we can solve this problem.
Let's see first what I meant about the different format of each errors
Implementation
1) For .NET MVC Controller Based Errors
Error code methods that MVC controller provides can take a format as a parameter
Create a folder to handle errors in the API folder
Add a class to provide a unified format
Add a constructor, properties, and a method as shown below
// constructor
public ErrorRes(int statusCode, string massage = null)
{
this.StatusCode = statusCode;
this.Message = massage ?? GetStatusCodeMessage(statusCode);
}
// properties
public int StatusCode { get; set; }
public string Message { get; set; }
// method
private string GetStatusCodeMessage(int statusCode)
{
return statusCode switch
{
400 => "bad request",
401 => "Unauthorized",
404 => "Resource not found",
500 => "Server error",
_ => null,
};
}
Use the class as a parameter to the MVC error method
2) For endpoints that does not exist
Add a controller to handle the reqeust to the not existing endpoint
Update the class as shown below
[ApiController]
[Route("errors/{code}")]
[ApiExplorerSettings(IgnoreApi = true)]
public class NotFoundController : ControllerBase
{
public IActionResult Error(int code)
{
return new ObjectResult(new ErrorRes(code));
}
}
Go to the Program.cs file and add the code below to redirect calls to unknown endpoints to the controller we just created
app.UseStatusCodePagesWithReExecute("/errors/{0}");
3) Adding Error Messages
Add a class that adds error messages
Inherit from the base error class and add additional properties (e.g., 'Details')
public class ErrorSource : ErrorRes
{
public ErrorSource(
int statusCode,
string massage = null,
string details = null
) : base(statusCode, massage)
{
this.Details = details;
}
public string Details { get; set; }
}
Create a folder for middleware
Add a class that handles the error
Insert this code
private readonly RequestDelegate _next;
private readonly ILogger<ExceptionMiddleware> _logger;
private readonly IHostEnvironment _env;
public ExceptionMiddleware(
RequestDelegate next,
ILogger<ExceptionMiddleware> logger,
IHostEnvironment env)
{
this._next = next;
this._logger = logger;
this._env = env;
}
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 res = _env.IsDevelopment() ? new ErrorSource(
(int)HttpStatusCode.InternalServerError,
ex.Message,
ex.StackTrace.ToString()
) : new ErrorSource((int)HttpStatusCode.InternalServerError);
var options = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};
var json = JsonSerializer.Serialize(res, options);
await context.Response.WriteAsync(json);
}
}
Go to the Program.cs file and register the middleware
4) Changing an Object to an Array of Strings
Error messages are provided by [ApiController] meta tag. So to change the format of provided error messages, we have to add an option to the meta tag
Create a class to handle this task
public class ErrorValidation : ErrorRes
{
public ErrorValidation() : base(400)
{
}
public IEnumerable<string> Errors { get; set; }
}
Go to the Program.cs file and register a service that changes [ApiController] settings
builder.Services.Configure<ApiBehaviorOptions>(opt =>
{
opt.InvalidModelStateResponseFactory = actionContext =>
{
var errors = actionContext.ModelState
.Where(e => e.Value.Errors.Count > 0)
.SelectMany(x => x.Value.Errors)
.Select(x => x.ErrorMessage).ToArray();
var errorRes = new ErrorValidation
{
Errors = errors
};
return new BadRequestObjectResult(errorRes);
};
});
We have seen how we can provide a better experience to frontend developers by sending them error message reponses with a unified format
'Marketing and SEO' 카테고리의 다른 글
Google Search (0) | 2023.04.21 |
---|---|
SEO (Multi-Lingual Blog Indexing) (9) | 2023.04.21 |
Robots.txt (0) | 2023.04.14 |