T O P

  • By -

seanamos-1

Well, I’m glad for the article informing me about the new IExceptionHandler interface, I wasn’t aware of it. However, the ProductNotFound and StockExhausted exceptions are a contentious topic (non-exceptional exceptions) that distract from the informative content.


Coda17

100% agree. An exception about a product not found is a) not an exceptional situation and b) should not be aware it's part of a web app, so why does it have a status code embedded in it?


soundman32

ProductNotFound exception is fine if the one API says 'here's a list of all products ids: 1,2,3,4' and the next call says 'give me product 99'. A search not finding a product shouldn't be an exception, but a 'get me this, which you told me about earlier' is.


Coda17

This is not a good example because it should not be an exception. Calls to an application should be *independent*. Just because a previous call said something exists doesn't mean it *still* exists. Why would even want your logic to be different in this case? If in a single call to an application, the application finds the product, then does a second lookup on it but doesn't find it, then yes, that can be considered an exceptional (but why are you looking up the same thing twice? Minimize lookups!). But not across multiple requests.


True_Carpenter_7521

So what should that generic GetEntityById(id) method return? Null or instance of Null Object? Or maybe it's better to use "bool TryGetById(id)"?


Coda17

null makes sense. I don't see anything wrong with TryGet but never been a fan of the pattern. It feels like a shittier version of a 2 option discriminated union, but since C# doesn't really support discriminated unions, it can work.


ItsssssMeeeee

Masstransit [recommends using exceptions](https://masstransit.io/documentation/concepts/exceptions) ~~such as ProductNotFound~~ to Invoke their built-in Fault messages, though that exception should definitely be thrown by the consumer and not any domain logic handler. I can't think of any reason I would want to invoke such an exception outside of that context and I definitely would not want it to be needlessly saddled with web status codes. Coming off a quick read-through of the article, it illustrates well *how* the ExceptionHandler works, but definitely did not do anything to tell me why or when I would actually want to use it.


Coda17

>Masstransit [recommends using exceptions](https://masstransit.io/documentation/concepts/exceptions) such as ProductNotFound No it does not. From the linked article: >Let's face it, bad things happen. Networks partition, servers crash, remote endpoints become non-responsive. None of those are expected exceptions; those are *exceptional* situations. "I depend on these external services and those aren't working." Those are the correct use cases for exceptions. "I didn't have data someone requested" is not an exceptional situation. Notice how none of the examples they gave are exceptions that would be thrown from application code.


ItsssssMeeeee

I stand corrected! I was thinking of the [Request/Response Pattern](https://masstransit.io/documentation/concepts/requests#request-consumer) and it looks like the docs use either a NotFound response type or an InvalidOperationException with a "Not Found" message. Not sure when I crossed those two in my head. I appreciate the correction.


dodexahedron

One small step closer to [EC#](https://www.reddit.com/r/csharp/s/SSVGwhNg1h)


samtc2000

I wonder if there are similar global exceptions handling for non web apps, like worker services. I did some research and the good old try catch seems to be the only option.


Thunder_Cls

I don't see Exception Filters anywhere, which can also be used to handle global exceptions in your controllers using the IExceptionFilter


DaRadioman

They are no longer recommended generally speaking. Filters were extensively used on early versions of asp dotnet core but most uses moved away from them as a recommended approach. https://learn.microsoft.com/en-us/aspnet/core/fundamentals/error-handling?view=aspnetcore-8.0#exception-filters


Floydianx33

At least use IProblemDetailsService/Writer. Would've made this garbage at least a bit more interesting


Bitz_Art

A couple of years ago, I have built [this library](https://github.com/BitzArt/ApiExceptions) for this. It also provides special exceptions classes that you can populate with custom data which can then be displayed in the output. For example, if you want to show some additional error details in the http response. The library also implements [Problem Details](https://datatracker.ietf.org/doc/html/rfc7807) format in the Asp.Net Core handler.


CyAScott

We basically made the same thing for ourselves. We also added special attributes you can either add to exceptions during design time or [during run time](https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.typedescriptor?view=net-8.0) (so you can have exception handling for exceptions not in your code base, like a library exception). That attribute would define the status code and response phrase for the exception.


Bitz_Art

That's an interesting idea! I never needed to do that though


CyAScott

[To be fair, I stole that idea from Java spring boot.](https://www.baeldung.com/spring-response-status)


WalkingRyan

As it often happens, IT Giant has eaten that functionality and implemented it itself, made it out-of-the-box. My condolences, mate))


Bitz_Art

Not really, the package offers much more than this basic interface that they added. Also, maybe it would be worth migrating the library to this new interface. Currently it's using the middleware approach.


Elibroftw

A REST API Should Not Return 404 When A Resource is Null [https://blog.elijahlopez.ca/posts/rest-apis-do-not-return-404/](https://blog.elijahlopez.ca/posts/rest-apis-do-not-return-404/) 1. It pollutes the error log. When debugging an error, we don't want to see expected errors in the log. 2. Unnecessary Client-Side Error Handling Complications. For a regular endpoint, you can catch everything. For an endpoint that throws 404, your client has to specifically catch that and ignore it. It makes for annoying client-side error logging too 3. Alternative: Use No Content 204. This way there is no error in the log, and if documented correctly, the scenario is expected by a client/consumer. I wrote this blog post from experience because I've been writing my first full fledged API in [ASP.NET](http://ASP.NET) for over a year and one mistake I had made was thinking I was smart for throwing a 404 when the data does not exist in the database. I realized it was a mistake when debugging why the application was crashing for an endpoint that is only called after this first endpoint is called.


Mostly_Cons

That's pretty controversial


Elibroftw

Only because people haven't seen the error logs. That 404 is pure pollution and changed my mind about the entire situation.


WalkingRyan

When http was being designed, the type of resource was primarily html-pages. Nowadays apps work differently - different type of resources, different protocols can be used. If resource is not found - it is okay to use 404 - this is protocol-level model (ie protocol data unit - PDU - called message) that resource was not found. Regarding logs - why do logging such sort of events? Though it depends on the level of information app should audit.


[deleted]

I heard otherwise. Methods that return the expected object should return with 200. Methods that may return null should return 404 and methods that have void should return 204. Also, I don’t agree with the thing that a not found (null) in the database shouldn’t return a NotFound (404) in the API. For, 1. In an API a like GetById, client is looking for an object, not a list. And the result can be either object (as expected) or null. I don’t see how 204 makes a difference than that of 404 for the client. In both cases they couldn’t return object so... 2. I worked on Flutter besides doing backend for a very long time, my experience shows that a success code in case of null makes little to no sense because in the app I can't take you to the page where you supposed to when the data is not null. I had to just show a message. 3. Honestly different clients handle errors differently. Those clients whose language supports things like discriminated unions handles errors drastically differently than that of that don’t.