mirror of
https://github.com/ivanch/ivanch.me.git
synced 2025-07-18 02:04:43 +00:00
Compare commits
4 Commits
6e3075d531
...
526e3fcee6
Author | SHA1 | Date | |
---|---|---|---|
526e3fcee6 | |||
3f3252b9e0 | |||
7cf9380556 | |||
8159799c16 |
104
content/posts/error-handling-dotnet.md
Normal file
104
content/posts/error-handling-dotnet.md
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
---
|
||||||
|
title: ".NET - Proper API error handling"
|
||||||
|
date: 2024-06-20T20:00:06-03:00
|
||||||
|
draft: false
|
||||||
|
summary: "Because returning stack traces isn't secure."
|
||||||
|
---
|
||||||
|
|
||||||
|
The main idea behind having centralized error handling is that we can process any unhandled exception to:
|
||||||
|
* Return formatted responses without revealing any internal functionality
|
||||||
|
* Process issues so that they are properly logged on logs or other monitoring systems (like Sentry)
|
||||||
|
* Make sure all errors have the same external behavior
|
||||||
|
|
||||||
|
For that, we will use a new middleware class:
|
||||||
|
```csharp
|
||||||
|
public class ErrorResponse
|
||||||
|
{
|
||||||
|
public string Message { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class ErrorHandlerMiddleware {
|
||||||
|
private readonly RequestDelegate _next;
|
||||||
|
private readonly ILogger<ErrorHandlerMiddleware> _logger;
|
||||||
|
private readonly IHostEnvironment _env;
|
||||||
|
|
||||||
|
public ErrorHandlerMiddleware(RequestDelegate next, ILogger<ErrorHandlerMiddleware> logger, IHostEnvironment env){
|
||||||
|
_next = next;
|
||||||
|
_logger = logger;
|
||||||
|
_env = env;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Invoke(HttpContext httpContext)
|
||||||
|
{
|
||||||
|
// Attempts to execute the next action on the http chain
|
||||||
|
// If it fails, we log the exception and trigger the HandleErrorAsync method
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _next(httpContext);
|
||||||
|
}
|
||||||
|
catch(Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "An unhandled exception has occurred: {Message}", ex.Message);
|
||||||
|
await HandleErrorAsync(httpContext, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task HandleErrorAsync(HttpContext context, Exception exception)
|
||||||
|
{
|
||||||
|
context.Response.ContentType = "application/json";
|
||||||
|
context.Response.StatusCode = (int) HttpStatusCode.InternalServerError;
|
||||||
|
|
||||||
|
ErrorResponse errorResponse;
|
||||||
|
|
||||||
|
if (_env.IsDevelopment())
|
||||||
|
{
|
||||||
|
// In development, we want to see the full details for easier debugging.
|
||||||
|
errorResponse = new ErrorResponse
|
||||||
|
{
|
||||||
|
Message = exception.ToString()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// In production, we return a generic message to avoid leaking details.
|
||||||
|
errorResponse = new ErrorResponse
|
||||||
|
{
|
||||||
|
Message = "An internal server error occurred. Please try again later."
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// We use the modern System.Text.Json for serialization via WriteAsJsonAsync
|
||||||
|
await context.Response.WriteAsJsonAsync(errorResponse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
We will also define a new Extension class to register this middleware:
|
||||||
|
```csharp
|
||||||
|
public static class ErrorHandlerExtensions
|
||||||
|
{
|
||||||
|
public static IApplicationBuilder UseErrorHandler(this IApplicationBuilder appBuilder)
|
||||||
|
{
|
||||||
|
return appBuilder.UseMiddleware<ErrorHandler>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
And then we just configure it on the `Configure()` method at the startup:
|
||||||
|
```csharp
|
||||||
|
public void Configure(IApplicationBuilder app)
|
||||||
|
{
|
||||||
|
app.UseErrorHandler();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Now, when there's an issue on the API execution, the API will return something like this:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"Message": "Internal Server Error"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Sources:
|
||||||
|
* [https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/write?view=aspnetcore-8.0](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/write?view=aspnetcore-8.0)
|
@ -5,26 +5,45 @@ draft: false
|
|||||||
summary: "Everyone should have Netflix at home"
|
summary: "Everyone should have Netflix at home"
|
||||||
---
|
---
|
||||||
|
|
||||||
Just having fun.
|
Those are some of the services that I use currently and that I find very useful. But maybe the hobby is going too far...
|
||||||
|
|
||||||
|
# Honorable Mentions:
|
||||||
|
* [Proxmox VE](https://www.proxmox.com/) - Got put those VMs somewhere.
|
||||||
|
* [Proxmox VE Helper Scripts](https://community-scripts.github.io/ProxmoxVE/) - easy deploys.
|
||||||
|
* [OpenMediaVault](https://www.openmediavault.org/) - NAS made simple.
|
||||||
|
|
||||||
|
## Necessary ones
|
||||||
|
* [AdGuard](https://hub.docker.com/r/adguard/adguardhome) - DNS-based Adblocker service (also useful to block malware and other unwanted things).
|
||||||
|
* Easy setup alternative: [PiHole](https://hub.docker.com/r/pihole/pihole) - Same thing, but easier to setup.
|
||||||
|
* [Portainer](https://www.portainer.io/) - Container management.
|
||||||
|
* Lightweight alternative: [Dockge](https://dockge.kuma.pet/) - Container and Compose management.
|
||||||
|
* [Nginx Proxy Manager](https://nginxproxymanager.com/) - Reverse proxy manager.
|
||||||
|
* Alternative: [Caddy](https://hub.docker.com/_/caddy)
|
||||||
|
* [WatchTower](https://containrrr.dev/watchtower/) - Automatic container updates.
|
||||||
|
* My lightweight alternative to this is my own `.sh` script that runs every 4 days that updates all containers on the server.
|
||||||
|
* [Paperless](https://docs.paperless-ngx.com/) - Keep those important documents and papers organized with easy searching.
|
||||||
|
|
||||||
## Misc
|
## Misc
|
||||||
* [Netdata](https://hub.docker.com/r/netdata/netdata/) - Server monitor.
|
* [Homarr](https://homarr.dev/) - A beautiful dashboard with all services and sometimes some nice widgets.
|
||||||
* [Heimdall](https://hub.docker.com/r/linuxserver/heimdall/) - Panel to add all your selfhosted services.
|
* [Beszel](https://beszel.dev/) - Server monitor with some useful alarms.
|
||||||
* [Statping](https://statping.com/) - Application ping.
|
* [Statping](https://statping.com/) - Application ping.
|
||||||
* [Uptime Kuma](https://uptime.kuma.pet/) - Application ping (beautier).
|
* Beautier alternative: [Uptime Kuma](https://uptime.kuma.pet/).
|
||||||
* [Gitea](https://gitea.com/) - Homemade GitHub.
|
* [Gitea](https://gitea.com/) - Homemade GitHub (with Actions!)
|
||||||
* [Notepad](https://github.com/pereorga/minimalist-web-notepad) - Homemade Dontpad.
|
* [Notepad](https://github.com/pereorga/minimalist-web-notepad) - Homemade dontpad.
|
||||||
* [Code Server](https://hub.docker.com/r/linuxserver/code-server/) - VSCode inside of a Docker.
|
* [Code Server](https://hub.docker.com/r/linuxserver/code-server/) - VSCode inside of a Docker.
|
||||||
* [FileBrowser](https://filebrowser.org/installation#docker/) - The name says by itself.
|
* [FileBrowser](https://filebrowser.org/installation#docker/) - Hosting files made easier.
|
||||||
* [Ngnix](https://hub.docker.com/_/nginx/) - Web server like this one.
|
* [Ngnix](https://hub.docker.com/_/nginx/) - Let's all love nginx.
|
||||||
|
* [WireGuard](https://hub.docker.com/r/linuxserver/wireguard) - Own personal VPN tunnel.
|
||||||
|
* [it-tools](https://hub.docker.com/r/corentinth/it-tools) - Some useful tools that we use every now and then.
|
||||||
|
|
||||||
## Media
|
## Media (*arr stack)
|
||||||
* [Transmission](https://hub.docker.com/r/linuxserver/transmission/) - Torrent client
|
* [Jellyfin](https://hub.docker.com/r/linuxserver/jellyfin/) - Homemade Netflix (I hate Plex).
|
||||||
* [Prowlarr](https://hub.docker.com/r/linuxserver/prowlarr/) - Indexer manager
|
* [Transmission](https://hub.docker.com/r/linuxserver/transmission/) - Torrent client with a simple web interface.
|
||||||
* [Sonarr](https://hub.docker.com/r/linuxserver/sonarr/) - TV shows management
|
* Alternative [qBitTorrent](https://hub.docker.com/r/linuxserver/qbittorrent) - I'm unlucky to setup it but ok, it's nicer.
|
||||||
* [Radarr](https://hub.docker.com/r/linuxserver/radarr/) - Movies management
|
* [Prowlarr](https://hub.docker.com/r/linuxserver/prowlarr/) - Torrent tracker aggregator.
|
||||||
* [Lidarr](https://hub.docker.com/r/linuxserver/lidarr/) - Music management
|
* [Sonarr](https://hub.docker.com/r/linuxserver/sonarr/) - TV shows management (Torrent integration).
|
||||||
* [Jellyfin](https://hub.docker.com/r/linuxserver/jellyfin/) - Homemade Netflix
|
* [Radarr](https://hub.docker.com/r/linuxserver/radarr/) - Movies management (Torrent integration).
|
||||||
|
* [Lidarr](https://hub.docker.com/r/linuxserver/lidarr/) - Music management (Torrent integration).
|
||||||
|
|
||||||
## Game server
|
## Game server
|
||||||
* [Minecraft Server](https://hub.docker.com/r/itzg/minecraft-server/) - The name says by itself².
|
* [Minecraft Server](https://hub.docker.com/r/itzg/minecraft-server/) - For that 2 week period every 3 years.
|
@ -1 +1 @@
|
|||||||
Subproject commit 9f1f414be805a2f94e2f51bd4be2b365ff12386d
|
Subproject commit 5a4651783fa9159123d947bd3511b355146d4797
|
Loading…
x
Reference in New Issue
Block a user