.NET class error reporting - best practises - c#

Up until recently we used custom exceptions with an inbuilt errorcode to allow us to communicate errors or problems we don't like around our systems.
However, I was shown a different method where you have a publicly exposed collection of errors on each class that you populate if there was a problem. The calling method then calls myObject.IsValid (which sees if the error collection has any entries) to check if the call was successful. If it wasn't then you can iterate through the error collection to see what went wrong. As far as I understand this is how MVC works with the ModelState.
The claim was this was the more efficient approach to error communication as there is an overhead to throwing exceptions.
Is this claim true? Is there a third option that is even better than the above? What is the correct way to communicate errors and problems around a .NET application?

Related

Standardisation of errors within my application

So I've been trying to standardise all the error handling within my application but I've not been able to standardise all.
First I replaced the IExceptionHandler by a custom exception handler by replacing it in the WebApiConfig like so
config.Services.Replace(typeof(IExceptionHandler), new CustomExceptionHandler());
After this almost all exceptions were handled using a specific error standard I want to use.
Shortly after, I noticed that my OWIN exceptions weren't caught in this so I created a middleware which is inserted before any other OWIN pipelines so it can catch the OWIN exceptions and once more return in standardised format.
Now I'm stuck with a new problem. When using ASP.NET WebAPI I try to create a few REST API's. Most exceptions caused by the validations within these API's are caught and standardised by the CustomExceptionHandler but not all.
When performing a GET request with an identification, for example:
.../test/api/superhero/marvel/wolverine%20
I get a default 404 from IIS. The reason is obvious. I'm looking for a resource which doesnt exist because of the encoded space in my URL. I've made sure to catch these kind of exceptions as well if I were to perform a request which I did not register such as:
.../test/api/superhero/ma4rvel/wolverine
But for some reason I can't catch this exception caused by a rogue encoded space. I've been looking into this and the closest I've gotten to influencing this is by using the IIS web configuration customError. While this is an option to do, I simply do not want to use MVC Views for this and want this solely to rely on C# compiled code.
So here I am wondering if anyone can offer me another option.
I should clarify that this is far from a must have and is more of a nice to have. An exception caused by something like this isn't going to happen very often and I'm fine with that, but if I'm able to fix this and once more standardise my errors then I'd be happy.
Does anyone have a suggestion for this?

Are there any general best practices for validation methods?

I was creating a common interface to verify operationality of data providers when a question came to my mind.
Essentially the method i'm looking at has a signature like Task<bool> TryConnectAsync();
While that method clearly indicates whether or not a provider will be able to work, it provides no generic way to point out what to do, if it cannot work (false).
Looking at for example the AspNetCore.Identity package, that issue was resolved by using the return type IdentityResult for any method which can succeed/fail on top of providing additional information on how to resolve issue or point out what went wrong.
I do not want to use exceptions in this case, since a connection failing is not a scenario which is entirely unexpected and would make the method handling wonky since the method is either true, or it throws an exception which delivers details on what went wrong.
I also do not want to dump that information just into logs - i want a library consumer to be able to decide whether to display that information or not.
So my question is:
Is an informational class which provides success/failure like AspNetCore.Identity the standard practice, or what other ways of handling this are there?
For google: How to handle success or failure of a method and provide additional information.
Not sure if the question is right here tho. Might be better suited for SE.

Making use of the ValidationException class

I have a situation where one of our developers wants to put a standard in place where we throw System.ComponentModel.DataAnnotations.ValidationExceptions in all our apps moving forward. An example would be that a user enters bad data into a form and our business logic layer throws a ValidationException which is handled at the calling layer.
However, I'm worried that this exception class is being used out of context and that one day we'll using some Dynamic Data Controls which make use of this exception and it will be difficult to tell the difference between when he's making use of the ValidationException vs times that the Dynamic Controls raise the exception.
We already use a custom exception class called something like "OurCustomException" and I think it would be better to just subclass off of that and create a OurCustomValidationException class. This way exceptions of different types can be clear cut.
Any opinions?
... it will be difficult to tell the
difference between when he's making
use of the ValidationException vs
times that the Dynamic Controls raise
the exception.
I think this is the main point you should be looking at when making that decision.
You seem to imply that the above (not being able to distinguish your own exceptions from "platform" validation exceptions) is a bad thing. That's not necessarily the case. IF you use the ValidationException exclusively to represent validation errors, then all your code can deal correctly with both your own and platform exceptions in the same way. No need to special-case platform exceptions from custom ones.
This is a win in my opinion. If you have both CustomException and ValidationException going back up to your toplevel layer for the same reasons, you'll have to repeat some logic one way or another. That's a bad thing (more maintenance, more chances of bugs creeping in).
So my opinion is that using the platform ValidationException is probably a good way to do it as long as you use it strictly for propagating validation problems.
Also think about the case where you would be giving/selling parts of your code to a third party (say it's real cool and you make a product out of it). It would probably be easier for the third party if your module throws "standard" exceptions (they can integrate it easily) rather than having to special-case all of his interface code for your module. Again, this is only valid if you stick with cases where a standard module would throw ValidationExceptions.
Lets look at it the other way around. You say:
our business logic layer throws a ValidationException
This is why I put strictly and exclusively above. You need to make sure you agree on what a validation error is. Lets look at two hypothetical problems:
"abc" is not a valid number
insufficient funds for this operation
For 1., the problem is simple/expected input validation error.
But in my opinion, 2. is not. It's a business logic problem. You could call it a validation issue (in the transaction, before the debit, you "validate" whether there are sufficient funds available) but I'd say its semantically very different.
I would advise not to put these two types of errors in the same exception "bag" as they have very different meanings, and may (often) lead to different application flow logic. (With the above two examples, 1. should keep the user on the very same form, as would any other "typo" kind of issue, but 2. should probably get him to a page that allows him to refill his account.)
To sum it up: using a standard exception seems like a good idea to me, as long as you stick with its expected semantics.

What's a good substitute for an enum?

I'm writing a web service that returns different types of errors.
Each method can return one of the three basic types of errors:
General, InvalidInput, or Non.
In addition to those three possible values, each method can have it's own errors (e.g. for SignIn method - InvalidPassword) - but each method can return only one error.
So for example the SignIn method will be able to return one of the following error types: General, InvalidInput, Non, InvalidPassword.
At first I thought of using enums, but I now think that the error types should implement inheritance because there are the basic three types, and each new method's error types inherit from that.. But I can't really think how. I thought of using a static class - but then it will only have one string static field - and inheritance is irrelevant again...
Another problem with enums is that what the web service's client will get eventually is a meaningless int (through json)
So my question is: What is a good way of conveying the idea that there are three basic possible values, and you can add to those to make a new type of errors?
It would be best if you reconsidered your interfaces.
It is by far better to use exceptions over error codes not only because it is so easy to forget about checking for an error code, but also because it is difficult to maintain them, keep them unique and meaningful.
John Saunders states in a similar thread:
[...] you should throw a SoapException. This will translate more or less directly into a SOAP Fault. A SOAP Fault is the appropriate way to indicate an error with a web service operation for the same reason that Exceptions are better than return status in a normal method - you don't have to check the return status at the point of the call.
Besides throwing a SoapException you may also throw arbitrary exceptions. ASP.NET will wrap these exceptions into a SoapException that gets passed to the client. The client can access the details of the exception in the inner exception of the SoapException.
For further explanations see also:
Handling and Throwing Exceptions in XML Web Services

How would you like an API to expose error handling?

This title begs for more explanation.
Basically, I'm rolling an API that wraps a web service in a nice heirarchical model. This model exposes things in the form:
var obj = MyRemoteResource.GetForId(1234, SourceEnum.ThatSource);
ApiConsumerMethod(obj.SomeProperty); //SomeProperty is lazily loaded, and often exposes such lazily loaded properties itself
... etc ...
Where many different RemoteResources* (each with many properties exist). There's really aggresive cacheing going on, and request throttling to prevent inadvertantly DOS'ing the servers (and getting the IP of the caller banned).
I've got all this code working, but I'm not doing much in the way of error handling at the moment. Basically, if the consumer of an API provides an invalid ID, the web server is down, a connection times out, or any other of a plethora of request layer errors occur an exception just percolates up when a property is accessed.
I consider this far less than ideal.
So my question is, how should I wrap these errors up so that it is convenient for a user of this API to manage them?
Some routes I have considered:
Just wrap all exceptions in some API defined ones, and document them as thrown.
Expose a static ErrorHandler class that allows a user to register notification callbacks for specific errors; falling back to the above behavior when no registration has been made for specific errors.**
Null properties on error, and set a LastErrorCode.
Each of these approachs have strengths and weaknesses. I'd appreciate opinons on them, as well as alternatives I haven't thought of.
If it impacts the discussion at all, the platform class throwing these exceptions is WebClient. Furthermore, usage of WebClient is sufficiently abstract that it could easily be replaced with some other download scheme if needed.
*Which is to say, many different classes
**This would be... wierd. But it maps to the global nature of the failure. This is my least favorite idea thus far.
I wouldn't implement fancy error technologies (like events and stuff like this). It's not easy to judge where and how to use exceptions, but this is no reason to implements other stuff.
When you request an object by an id which doesn't exist, what do you have to tell the caller about this? If you just return null, the client knows that it doesn't exist, there is nothing more to say.
Exceptions force the caller to care about it. So they should only be used where the caller is expected to do something special. Exception can provide the information why something didn't work. But if it is an "error" the user could also ignore, an exception is not the best choice.
There are two common alternatives to exceptions.
Use return values which provide information about the result of an action. For instance, logon could return a LogonResult instead of throwing an exception.
Write two methods, one throwing an exception, and one (Try...) returning a boolean. The caller decides if it wants to ignore the "error" or not.
Personally I believe this is entirely dependent on the context of what your API end-user is trying to do. If this is the case, you should let them decide how to handle erors.
Recently when working with CSV files (very error prone) I used an API that allowed you to define the exception behaviour. You could either ignore the error, replace by some default value/action, or pass them off to an event handler.
I really liked this approach of letting the end user decide how to handle internal exceptions, because unless your API is very specific its difficult to preempt all scenarios.
I prefer to have an exception thrown at me when something bad happens. Exceptions are (for me, anyways) the common way to tell that something went wrong, and i find it more intuitive to catch, than to check a return value for null and check another property to see what went wrong..

Categories

Resources