I have an n-tier web application, and I want to catch a specific type of exception in every method coming from the DAL (Data access layer) and rethrow it as a new exception of a specific type.
There are many methods in my DAL, so I don't want to start wrapping each one with try/catch.
I think this is possible using the Exception Handling Application Blocks, but i couldn't find any good documentation of how to do this...
I'm not familiar with the previous versions of the application blocks neither.
Has your DAL repositories got an interface?
I would implement the interface using a decorator pattern.
All the decorator does catches the exception and then builds a new exception and throws that out to the upper tier
As a point of note, in our n-tiered applications we always let exception just get thrown naturally and catch them in once single place and log them. We only create specific exceptions if we absolutely have to and that would be rare enough.
The reason for this is maintainability of code. Code can easily become unreadable when try/catches exist everywhere.
Related
I have a question about the clean architecture I use to write my project, I need to tackle the subject of exceptions.
In the project I am using CQRS which is located in the application layer and which orchestrates the whole operation and component connection. In the domain layer, I have domain objects that have some logic, if there is an error this layer throws an exception BusinessRuleValidationException, or NullReferenceException in this layer I only use these 2 exceptions, but now I have an infrastructure layer which, if necessary, also throws exceptions, but there are more of them in this layer and they will probably continue to grow as the application develops.
Now the question is how to solve this problem, which are exceptions that I wouldn't want to keep remembering about handling every single exception inside api using exception middleware. My idea is to leave the exceptions in the domain layer as they are, because there are only 2 and write a decorator to MediatR that will catch exceptions from the domain layer only and make them consistent across the api, i.e. add a unified response so that exceptions are not sent to the user from its internal message, only consistent for everyone, in the form of Result using the Fluent Results bundle. Instead of throwing exceptions in Infrastructure, use a Fluent Results package that will return errors instead of exceptions and eventually return Result from all MediatR Handers. I would not like to use Fluent Result inside the domain layer because it is kind of breaking the rule that the domain layer doesn't have any references to other things.
The next question, if I decide to solve the problem in one way or another, the results of errors from the Infrastructure should immediately contain an error code such as Api should return to the end user, e.g. if occurs an error because it is impossible to connect to the database, the infrastructure should return, the message (Result) under the title "Could not connect to the database" with the code "500", or rather this error code should be returned from the api itself, ie the controller gets an error (Result) and it decides what code to give to this error.
Thanks for help :)
Exceptions aren't a problem that you need to solve.
Exceptions are there to say something unexpected has happened, and there are many many things that can go wrong: incorrect input, timeouts, not authorised, not authenticated, missing data, etc, etc.
You can structure your code, where it reuses .net exceptions as much as possible, and if you have to add something that is unique to your business domain, you put that in the layer that throws those exceptions. If this happens at the networking level, you put exceptions there. If this is domain logic validation - you can keep it in the domain core.
Consuming code may or may not catch the exception. If it catches the exception, the code import the exception from the current layer or the layer below.
PS: don't throw null reference exceptions
public class PageNotFoundException : HttpException
{
public PageNotFoundException()
: base(404, "HTTP/1.1 404 Not Found")
{
}
}
The idea is that rather than typing this each time
throw new HttpException(404, "HTTP/1.1 404 Not Found")
I'd rather write
throw new PageNotFoundException();
I was going to add an overload for including the innerException however I will never use this in a try/catch block.
Would you consider this good practice?
i.e. Inheriting from an exception and passing hardcoded information to base(...).
I decided to rewrite my answer to be specific to your actual question, and in a more broad sense that an MVC application isn't the only thing these best-practices apply to.
(1) Answer. This is not good practice. You should use a exception builder method instead that throws HttpException directly.
public static void ThrowPageNotFoundException() {
throw new HttpException((Int32)HttpStatusCode.NotFound, "HTTP/1.1 404 Not Found");
}
(2) DO. Use exception builder methods (eg. the code I provided). This allows for you to avoid the extra performance cost of having your own exception type, and allows for it to be inlined. Members throwing exceptions do not get inlined. This would be the proper substitute for convenience throwing.
(3) DO. Use base class library exceptions whenever possible, and only create a custom exception when there is absolutely no base exception that meets the needed requirements. Creating custom exceptions adds deeper exception hierarchy, which makes debugging harder when it does not need to be, adds extra performance overhead, and also adds extra bloat to your code base.
(4) Do NOT. Throw the base class System.Exception. Use a specific exception type instead.
(5) Do NOT. Create custom exceptions for convenience. This is not a good reason for a custom exception, because exceptions are intrinsically costly.
(6) Do NOT. Create custom exceptions just to have your own exception type.
(7) Do NOT. Throw exceptions that can be avoided by changing the calling code. This would suggest that you have a usability error in the API rather than an actual problem.
Anyone who has read Framework Design Guidelines from the .NET development series will know these practices, and they are very good practices. These are the very practices that the .NET framework was built upon, and MVC as well.
If you are the one throwing the exception in the first place, then yes - it's OK. However, if you catch an HttpException and then try to throw a PageNotFoundException instead, you should put the original exception as the InnerException.
While this is a nice construct in your own code for your own use, one consideration is that it can promote coding by convention which can be dangerous when you're dealing with other/new developers.
In your own libraries, if you are consistent about throwing a PageNotFoundException whenever a 404 HttpException should be thrown, it might make more sense to catch (PageNotFoundException). However, when you start using other libraries that don't have your custom exception, you will miss 404 HttpExceptions thrown by other code. Likewise, if you have other developers contributing at a later date (or even your own additions in the future), the consideration that PageNotFoundExceptions are what's being caught by most of the functionality may be missed and new 404 HttpExceptions could be thrown in the new modules, which would likewise not be caught by copy/pasted calling code.
Basically, constructs like this increase the acclimation time required for working on the project, and should be handled in such a way that this cost is minimized (made sufficiently visible in an easy to find central shared objects library that isn't already too cluttered).
On the other hand, there is certainly value in centralizing the generation of your HttpExceptions if you're what looking for is essentially the factory pattern benefits; it may be worth just going with that instead if that's what you're trying to get out of it (throw ExceptionFactory.NewPageNotFound()).
I'm designing a class library that will be sent out to the public for use with their applications. It interacts with a custom db system that they need to install on their servers.
I'm having trouble deciding how to throw exceptions from this dll which is mainly a wrapper to the custom db system.
I assume I have to create custom exceptions that can indicate various types of errors, including validations, data integrity errors etc.
This dll will be eventually used by public facing web sites. I would like to provide a good feedback to the end user by throwing proper exceptions so that the site can make a decision to display them or not. But I'm not sure if it is possible to anticipate all the user input errors. In case of an unexcepted event, do I just throw a regular .net exception with the error message?
I have used many third party dlls that do not give you a clear way to handle the errors and I don't want to be one of them.
The only reason to creaqte a custom exception is if the calling code needs to catch it explicitly to know the difference between your exception and some other exception.
If the caller is going to treat your exception exactly the same as, say, InvalidOperationException, then you should throw InvalidOperationException instead.
See Choosing the Right Type of Exception to Throw.
You should rethrow custom exceptions where your DLL knows more about the error than is indicated in the exception you are catching, if you don't know about it, then you don't know MORE about it, just pass it along.
Just to be clear, this doesn't mean you can't throw your own exceptions on detecting errors.
I'm working on a logging program, and I'd like to avoid processing the same Exception object repeatedly when it is being logged repeatedly because it is percolating up through a nested call structure. So I'd like to be able to format the Exception object once, and give the formatted version a unique "exception number" and then tag the Exception object somehow so I can recognize it if it turns up again in a later log call.
The idea I've come up with is to misuse the HelpLink field of the Exception object. I'll set it to contain a string version of my "exception number". Then I can recognize the Exception object if it shows up again momentarily in another log call.
But is this maybe a bad idea? Are there any gotchas involved that I haven't thought of? If so, does anyone have a better idea?
EDIT:
To explain the situation a bit more, this logger will only be used on my own programs.
Instead of 'abusing' HelpLink property, you could use Data property to add extra information to the Exception. It contains key/value pairs that provide additional user-defined information about the exception.
While I agree with TheVillageIdiot, I would point out that more generally speaking, if you want to change the behavior of Exception, then you should create your own Exception class that add's additional pertinent information. That's why we use inheritance and polymorphism, after all. :)
Definitely it is not okay to use Exception.HelpLink because logger should be concerned with logging the exception information only in given format or any default format. If same exception is coming again and again it is problem of the executing assembly or program not the logger.
Better still you can explore the options of using log4net for logging and custom reporting interface to format/group exception from the log files or database tables created/updated by log4.net
No it is not acceptable to misuse the HelpLink. As #Greebo mentioned if you need additional properties you could create your own exception classes. An alternative might be to use the Data property that is part of the System.Exception class.
Question: Are your exception handlers doing any handling other than logging?
If not then most likely your don't need the handlers. Just let the exception (using a finally block for cleanup) bubble up the call stack and handle it at the outmost layer. If your handlers are handling the exception then I'm not sure why you would have the same exception further up the stack. I would think it would be more likely that you would create a new exception setting the inner exception to the one that was handled.
Your code should not be catching and logging the exception at every level. There's no reason that your code should ever be seeing the same exception twice. This sounds very much like you are using "catch every exception", which is a major anti-pattern.
What is the best practise for returning an error of a business rule in a BLL? SHould I just raise exceptions and catch them in the presentation layer, shoudl I return some kind of object that holds any exception type info?
The word "returning" is tricky here.
The primary virtue of multi-tier design is orthogonality. You should be able to call the classes in your BLL from an entirely different UI than the one you're currently using and handle logging completely differently.
If an exception is able to be handled without user intervention or notification, you should generally do so within the BLL. If the exception needs to be brought to the user's attention or logged, let it bubble up to the UI, which can implement notification and logging without building such things into the BLL.