All Projects → JosephWoodward → Globalexceptionhandlerdotnet

JosephWoodward / Globalexceptionhandlerdotnet

Licence: mit
Exception handling as a convention in the ASP.NET Core request pipeline

Projects that are alternatives of or similar to Globalexceptionhandlerdotnet

Event Sourcing Jambo
An Hexagonal Architecture with DDD + Aggregates + Event Sourcing using .NET Core, Kafka e MongoDB (Blog Engine)
Stars: ✭ 159 (-32.05%)
Mutual labels:  webapi
Diamond
Diamond is a full-stack web-framework written in The D Programming Language using vibe.d
Stars: ✭ 173 (-26.07%)
Mutual labels:  webapi
Grapefruit.vucore
A front-background project using ASP.NET Core WebApi and Vue.js
Stars: ✭ 210 (-10.26%)
Mutual labels:  webapi
Webapimongodb
Using MongoDB with ASP.NET Web API and ASP.NET Core to perform CRUD operations and build a NotebookApp
Stars: ✭ 164 (-29.91%)
Mutual labels:  webapi
Viennanet
Framework for quickly creating enterprise microservices on .NET Core https://habr.com/ru/company/raiffeisenbank/blog/516540/
Stars: ✭ 170 (-27.35%)
Mutual labels:  webapi
Denunciado
This project born from the need from people to have a way of communication between municipalities and communities. Some municipalities, have their platforms, but they are complex to validate the veracity of complaints. Denounced, it was born with the purpose of offering a free platform to these municipalities. Denounced consists of three main modules developed with Microsoft technologies, using the .Net Framework and Xamarin for its development: 1. Back End Web Project: Module of administration of the complaints, by the employees of the town councils. In this tool, the employees of the city council receive, validate, report and close the complaints, after being served. 2. Web Portal Client: It consists of a web project, so that the community make their complaints, in the same, the users of the service create a profile, must specify when making their complaint, evidence to support this. Through the portal, they can see the complaints of other community members, follow it, give their opinion or provide possible solutions or more evidence. 3. Mobile Project: It has the same functionalities as the web portal, with the addition, that the automatic location can be sent, from the cell phone.
Stars: ✭ 183 (-21.79%)
Mutual labels:  webapi
Httpcode.core
简单、易用、高效 一个有态度的开源.Net Http请求框架!可以用制作爬虫,api请求等等。
Stars: ✭ 146 (-37.61%)
Mutual labels:  net-core
Dotnet New Caju
Learn Clean Architecture with .NET Core 3.0 🔥
Stars: ✭ 228 (-2.56%)
Mutual labels:  webapi
Goldeneye
The CQRS flavoured framework that will speed up your WebAPI and Microservices development
Stars: ✭ 171 (-26.92%)
Mutual labels:  webapi
Urf.net
Unit of Work & Repositories Framework - .NET 4.x
Stars: ✭ 202 (-13.68%)
Mutual labels:  webapi
Active Directory B2c Dotnet Webapp And Webapi
A combined sample for a .NET web application that calls a .NET Web API, both secured using Azure AD B2C
Stars: ✭ 166 (-29.06%)
Mutual labels:  webapi
Devicemanager.api
Web API Framework demonstrates scalable, multitenant, architecture and allows building its own solution in the minutes. Uses: Entity Framework, UnitOfWork, Repository patterns. Wrapped in Docker, Kubernetes
Stars: ✭ 168 (-28.21%)
Mutual labels:  webapi
Servicestack.redis
.NET's leading C# Redis Client
Stars: ✭ 2,236 (+855.56%)
Mutual labels:  net-core
Gweb
Interact with browser from Go. Manually-crafted WebAPI interoperation library.
Stars: ✭ 163 (-30.34%)
Mutual labels:  webapi
Angularspawebapi
Angular Single Page Application with an ASP.NET Core Web API that uses token authentication
Stars: ✭ 222 (-5.13%)
Mutual labels:  webapi
Corporate Bs Generator Api
Corporate Bullshit(BuzzWord) Generator API
Stars: ✭ 155 (-33.76%)
Mutual labels:  webapi
Abp React Antd
一个基于 ABP + React + Ant Design Pro 的快速开发框架
Stars: ✭ 175 (-25.21%)
Mutual labels:  net-core
Opentouryo
”Open棟梁”は、長年の.NETアプリケーション開発実績にて蓄積したノウハウに基づき開発した.NET用アプリケーション フレームワークです。 (”OpenTouryo” , is an application framework for .NET which was developed using the accumulated know-how with a long track record in .NET application development.)
Stars: ✭ 233 (-0.43%)
Mutual labels:  webapi
Urf.core
Unit of Work & Repositories Framework - .NET Core, NET Standard, Entity Framework Core. 100% extensible & lightweight. Live demo: https://goo.gl/QpJVgd
Stars: ✭ 226 (-3.42%)
Mutual labels:  webapi
Minicover
Cross platform code coverage tool for .NET Core
Stars: ✭ 193 (-17.52%)
Mutual labels:  net-core

Global Exception Handling for ASP.NET Core

Build status

GlobalExceptionHandler.NET allows you to configure application level exception handling as a convention within your ASP.NET Core application, opposed to explicitly handling exceptions within each controller action.

Configuring your error handling this way reaps the following benefits:

  • Centralised location for handling errors
  • Reduce boilerplate try-catch logic in your controllers
  • Catch and appropriately handle exceptions outside of the ASP.NET Core framework
  • You don't want error codes being visible by consuming APIs (for instance, you want to return 500 for every exception)

This middleware targets the ASP.NET Core pipeline with an optional dependency on the MVC framework for content negotiation if so desired.

Note: GlobalExceptionHandler.NET builds on top of the app.UseExceptionHandler() middleware so they cannot be used in tandem. GlobalExceptionHandler.NET turns your exception configuration provided by this library into an ExceptionHandler used within the UseExceptionHandler middleware.

Installation

GlobalExceptionHandler is available on NuGet and can be installed via the below commands depending on your platform:

$ Install-Package GlobalExceptionHandler

or via the .NET Core CLI:

$ dotnet add package GlobalExceptionHandler

Bare Bones Setup

// Startup.cs

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    // app.UseExceptionHandler(); You no longer need this.
    app.UseGlobalExceptionHandler(x => {
        x.ContentType = "application/json";
        x.ResponseBody(s => JsonConvert.SerializeObject(new
        {
            Message = "An error occurred whilst processing your request"
        }));
    });
    
    app.Map("/error", x => x.Run(y => throw new Exception()));
}

Any exception thrown by your application will result in the follow response:

HTTP/1.1 500 Internal Server Error
Date: Fri, 24 Nov 2017 09:17:05 GMT
Content-Type: application/json
Server: Kestrel
Cache-Control: no-cache
Pragma: no-cache
Transfer-Encoding: chunked
Expires: -1

{
  "Message": "An error occurred whilst processing your request"
}

Handling specific exceptions

You can explicitly handle exceptions like so:

app.UseGlobalExceptionHandler(x => {
    x.ContentType = "application/json";
    x.ResponseBody(s => JsonConvert.SerializeObject(new
    {
        Message = "An error occurred whilst processing your request"
    }));

    x.Map<RecordNotFoundException>().ToStatusCode(StatusCodes.Status404NotFound);
});
HTTP/1.1 404 Not Found
Date: Sat, 25 Nov 2017 01:47:51 GMT
Content-Type: application/json
Server: Kestrel
Cache-Control: no-cache
Pragma: no-cache
Transfer-Encoding: chunked
Expires: -1

{
  "Message": "An error occurred whilst processing your request"
}

Runtime Status Code

If talking to a remote service, you could optionally choose to forward the status code on, or propagate it via the exception using the following ToStatusCode(..) overload:

app.UseGlobalExceptionHandler(x =>
{
    x.ContentType = "application/json";
    x.Map<HttpNotFoundException>().ToStatusCode(ex => ex.StatusCode).WithBody((e, c) => "Resource could not be found");
    ...
});

Per exception responses

Or provide a custom error response for the exception type thrown:

app.UseGlobalExceptionHandler(x => {
    x.ContentType = "application/json";
    x.ResponseBody(s => JsonConvert.SerializeObject(new
    {
        Message = "An error occurred whilst processing your request"
    }));

    x.Map<RecordNotFoundException>().ToStatusCode(StatusCodes.Status404NotFound)
        .WithBody((ex, context) => JsonConvert.SerializeObject(new {
            Message = "Resource could not be found"
        }));
});

Response:

HTTP/1.1 404 Not Found
...
{
  "Message": "Resource could not be found"
}

Alternatively you could output the exception content if you prefer:

app.UseGlobalExceptionHandler(x => {
    x.ContentType = "application/json";
    x.ResponseBody(s => JsonConvert.SerializeObject(new
    {
        Message = "An error occurred whilst processing your request"
    }));

    x.Map<RecordNotFoundException>().ToStatusCode(StatusCodes.Status404NotFound)
        .WithBody((ex, context) => JsonConvert.SerializeObject(new {
            Message = ex.Message
        }));
});

Content Negotiation

GlobalExceptionHandlerDotNet plugs into the .NET Core pipeline, meaning you can also take advantage of content negotiation provided by the ASP.NET Core MVC framework, enabling the clients to dictate the preferred content type.

To enable content negotiation against ASP.NET Core MVC you will need to include the GlobalExceptionHandler.ContentNegotiation.Mvc package.

Note: Content negotiation is handled by ASP.NET Core MVC so this takes a dependency on MVC.

//Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvcCore().AddXmlSerializerFormatters();
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseGlobalExceptionHandler(x =>
    {
        x.Map<RecordNotFoundException>().ToStatusCode(StatusCodes.Status404NotFound)
            .WithBody(e => new ErrorResponse
            {
                Message = e.Message
            });
    });

    app.Map("/error", x => x.Run(y => throw new RecordNotFoundException("Resource could not be found")));
}

Now when an exception is thrown and the consumer has provided the Accept header:

GET /api/demo HTTP/1.1
Host: localhost:5000
Accept: text/xml

The response will be formatted according to the Accept header value:

HTTP/1.1 404 Not Found
Date: Tue, 05 Dec 2017 08:49:07 GMT
Content-Type: text/xml; charset=utf-8
Server: Kestrel
Cache-Control: no-cache
Pragma: no-cache
Transfer-Encoding: chunked
Expires: -1

<ErrorResponse 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Message>Resource could not be found</Message>
</ErrorResponse>

Logging

Under most circumstances you'll want to keep a log of any exceptions thrown in your log aggregator of choice. You can do this via the OnError endpoint:

x.OnError((exception, httpContext) =>
{
    _logger.Error(exception.Message);
    return Task.CompletedTask;
});

Configuration Options:

  • ContentType
    Specify the returned content type (default is application/json).

  • ResponseBody(...)
    Set a default response body that any unhandled exception will trigger.

x.ResponseBody((ex, context) => {
    return "Oops, something went wrong! Check the logs for more information.";
});
  • DebugMode Enabling debug mode will cause GlobalExceptionHandlerDotNet to return the full exception thrown. This is disabled by default and should not be set in production.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].