I am working on re-writing a business layer for one of the apps in company. For now, the business layer will interface directly with the web client. But in the future, it will be encapsulated with service interfaces and will be consumed by the same web client.
My question is that when a validation exception or other exceptions occur in the business layer, is it okay to throw custom exceptions or would it be better to use custom objects that represent errors ... like ValidationError, etc? Is it more expensive to throw an exception vs returning an object?
The most popular thought on this today is to throw the errors towards the application layer. I guess the idea is so that the interpretation of what went wrong and telling the user is more clear there than way down in the guts of the applications.
Some people catch errors everywhere and then throw them as they go, this leaves a trail of traceable documentation for the developer.
One other interesting point, if the developer makes all the error messages contain unique identifiers, then they are easily able to debug because they can pinpoint the code just by looking for that number.
Throwing an exception is way more expensive than returning an object. Exceptions should be used only for unexpected situations. Errors in validation of user input is not unexpected and should not result in an exception being thrown.
Related
I have a C# console project where I have separated out the business logic from the UI. The business logic calls an API, retrieves JSON data, and then updates a database with the data. The UI handles the display of the results and also loops through a queue to process records with the business logic.
My question is how to properly handle exceptions thrown by the business logic. The UI project currently handles exceptions that bubble up but I want to give as detailed an error message as possible. For example, sometimes the API fails to authorize or may be down and I want to log that specific exception. The problem is the UI project does not know anything about HttpRequestException without me adding a reference to the System.Net.Http library, which creates a dependency I don't want.
What is the "best practice" for handling exceptions in a project other than where they are generated?
If you want to pass detailed messages to the UI project without explicitly referencing System.Net.Http, consider catching these HTTP exceptions in the business logic, wrapping them in an exception type you define in that library, and re-throwing the new exception. Then your UI library only needs to know about the business logic library, which it's already referencing, and the business logic can provide the most informative message possible for things it can't properly recover from.
I'd say the best practice is to not handle them. You don't know what those exceptions are, so how can you "handle" them?
Either trust the Message property of these exceptions and display them to the users, or just tell the users "sorry, something bad happened".
Keep in mind that your users will need to read the detailed messages and decide what to do about them. Quite likely they'll either ignore the messages or else call someone to ask what to do about them. Make sure you log enough information to answer the call. Sometimes, you're just better off displaying a message that says, "Please call someone who can figure out what went wrong".
I don't really know the best way to handle exception in an multi-language application.
Where should I handle the translation of the error message (Exception.Message)?
Shall I translate the message in the ctor as soon as I throw the exception?
throw new MyException("Error message", Resource.MyException_TranslatedMessage);
Or do I throw the exception and I use a home made helper that will find the error message using the type of the exception in the logic of the View?
try
{
//...
}
catch(Exception ex)
{
myLabel.Text = new ExceptionTranslator(ex).Translate();
}
Or, does Microsoft offer a tool or a mechanism to do that?
In a word: what are the good practices to handle exception messages translation?
Most exceptions are there for technical purposes, unless your operations and maintenance crew are also located in different countries, those exceptions should simply have messages in the language of the people who write and maintain the application.
The .NET framework contains localized exception messages. For me as a developer, that's very annoying, since the exception messages in my local language (Dutch) don't mean as much as the original English exception messages. However, it seems reasonable for Microsoft to localize those framework exception messages, since their target audience can be located anywhere.
Some types of exceptions however, are explicitly thrown to be displayed to the user. These are your ValidationException or BusinessLayerException. Their clear contract is to be displayed to the user. Of course you should localize those exception messages, but instead of translating them, it's often much better and easier to pull the exception message from a localized resource when throwing the exception:
throw new ValidationException(Resources.InvalidUserName);
Much better to only translate it when it needs to be displayed, IMHO.
This applies to any localisable string, not just error messages.
Ideally, the logic of the code shouldn't care about the content - or language - of the message, it's only interested in the type of the exception. It's only the presentation layer that (might) need to display it in the local language.
The external code should not translate messages
throw new MyException("Error message", Resource.MyException_TranslatedMessage);
This is best solution in my mind
We are Refactoring (and of-course redesigning) our Services in layered design.
We have Service operations layer (BLL), Network abstraction layer -> (deals with network proxy), Data abstraction layer.
But we are a bit baffled about our exception handling strategy.
We don't want to expose too much information from BLL to outside world. (from other layers to bll is fine)
We don't want to clutter the code with try catch stacks
We don't want to mess the exception handling code(like logging, emailing etc) in catch blocks
Could someone post some code samples or literature pointers which we can use to design our simple exception handling framework?
We don't want to expose too much information from BLL to outside world.
(from other layers to bll is fine)
It's BLL itself that defines what's exposed. Make sure You show what's intended to be seen.
We don't want to clutter the code with try catch stacks
Then don't. Exceptions are exceptions. Don't control flow using them. Let them blow up.
We don't want to mess the exception handling code(like logging, emailing etc) in catch blocks
If Your logic does not rely on exception handling (which it should not) and Your code guards itself (this one is important, Your application should ALWAYS blow up on invalid state instead of working further. otherwise - it's hard to understand what causes what), then it's more than enough with wrapping whole app with only 1 error handler that dumps stack trace where necessary.
E.g. - in .net, You can use subscribing to appdomain unhandled exception event for that.
I personally use ELMAH for my web application - few lines in app.config and I have nice error log, stored in sqlite, easily accessable from web app itself. That's about all error handling I got.
Eric Lippert has a wonderful article on how to handle exceptions. I think it would be useful.
Exception handing can be as complex as you want but the good way is to use some global definition. For example by aspects which you can build with any AOP framework - part of most IoC containers like Unity, Windsor Castle, Spring.NET. Separate category of AOP frameworks is PostSharp which adds aspects on compile time insted of runtime.
Also you can check Enterprise Library 5.0 and its Exception handling application block which allows you to do policy based exception handling out of the box.
In our app, we use components developed by other teams. The question was how can I define a nicely way of exception handling than this
try
{
someComponent.DoStuff();
}
catch (Exception ex)
{
textLabel= ex.Message;
}
The component has no custom exception type, maybe a nicely way to do it would be to define a component specific Exception type and wrap this somehow?
I know the question is very basic, but I am interested more in the let's say how it is good to do it. If you call another component with no custom defined exception types, how do you handle any potential exceptions in an elegant way?
Ideally you would have the component development team do this for you - how else do they expect their clients to recognize and handle errors from their component? Scoping the exceptions that a component can raise is a fundamental part of good C# design.
If that's not an option, then implementing your own wrapper on top of the component to taxonomize its failure cases sounds like a good second best, and very noble of you into the bargain.
If the third-party library is poorly documented (they don't specify the exceptions that can be thrown by each method), there are tools available that can Reflect into the code and determine the possible Exceptions that may be thrown. This can get a bit daunting (there are a surprising number of exceptions that can be thrown for any given call), but it's better in principle than catching the general Exception type. Here is one commercial product that performs this type of analysis.
When you catch an error you are able to repackage it and then throw another error, at the most basic level you may just be adding more data - but, from what you've suggested, you could also replace the generic error with a custom error that, whilst it won't overcome the limitations of the response you've got from the component, would give the code further up the call stack the opportunity to respond more appropriately.
So in terms of just adding information in the most basic manner - by throwing a new exception with some additional text whilst still passing the original exception:
catch (Exception ex)
{
throw new Exception("This is more about where the exception occurred", ex);
}
Now, if you want to define your own custom component exception you change the new Exception to new ComponentSpecificException adding data as necessary to the constructor but never forgetting to set the inner exception. Exceptions also have a data collection of key, value pairs into which you can insert more information (by creating the exception, adding the data and then doing the throw).
That's all fairly generic - working forward from there, where you can't necessarily anticipate all the exceptions you have to handle you don't try - you set up logging so that you know when you've got a generic exception i.e. one that hits the final catch - and then over time add exception specific catches above the generic to provide more appropriate responses or, at the very least, package up the error into less general custom exceptions.
Not sure I've explained that very well - but the notion is that as its difficult to anticipate every possible error you want to have a strategy to develop your application in a systematic fashion as you discover new exceptions.
Assuming you want to catch every type of exception, this solution looks fine to me.
Either from your knowledge of using the component, or by using something like Reflector to analyze the compiled component, what possible exceptions can this component throw? Would providing exception handlers for these allow you to provide better feedback to you users?
The only reasonable (much less "elegant") way to handle exceptions is to log them if you can't recover from them.
Then notify the user there was a problem and offer them the chance to try again (if it's an interactive program).
If your application is exclusively for .NET developers, go ahead and show them the exception message (though Exception.ToString is better, since it includes a stack trace). Otherwise, don't display exception messages in your user interface - that's a security hole and will only confuse your users.
How do I implement error handling elegantly? For example, my data access layer can potentially throw 2 types of errors:
1) not authorized access, in which case the page should hide everything and just show the error message
2) errors that inform the user that something like this already exists in the database (say name not unique - for example), and in this case I wouldn't want to hide everything.
EDITED:
As a result of some comments here I devised that I should create derived specialized exception types, such as NotAuthorizedException, DuplicateException, etc etc.... it's all fine and dandy, however I can see 2 problems potentially:
1) Every stored proc has a return field p_error where it contains an error message. Upon getting the data from DB, I need to check this field to see what type of an error has been returned, so I can throw an appropriate exceptions. So, I still need to store my error types/error messages somewhere.....In other words, how do I should the exact message to the user (at certain times I need to) w/o checking the p_error field first. WHich brings me back to error object. Anyone?
2) I can this potentially turning into a nightmare where the number of exceptions equals the number of error message types.
Am I missing something here?
Much thanks to everyone!
You should check out the exception handling block in Enterprise Library. Lots of good tips and codeware surrounding wrapping exceptions and passing them between layers.
Where's your business layer, and why isn't it checking Authorization and integrity? The DAL is too low level to be checking those rules - if you hit a problem there, it's pretty much time to throw an exception. Your business layer or controllers can catch that exception, and display a reasonable message - but it's not something you should regularly be doing.
Create your own exception layer.
DALExceptionManager
DuplicateException
DatabaseException
BLLExceptionManager
NotAuthorizedException
InvalidDateException
In your Presentation Layer, Add this references and create a common exception handler.
In this way you know how to deal with the exception messages.
One option that I was thinking of
using is create an Error class, but
then I would need to pass it from UI
to business layer and the then to data
access layer by reference
I am not sure I understand this. You don't have to pass the error object in every layer. For example, in one of your example, errors that inform the user that something like this already exists in the database (say name not unique - for example) , a sql exception could be thrown by the framework, and you just need to catch the specific exception in your business layer, or UI layer.
Exception handling block by the Enterprise library suggested by other people will allow you define some policy-based exception handling in your web.config file. It could be good place if you want to develop some enterprise application. But for simple application, you may need not go that far.
What happens in the upper layers isn't up to your Data Access Layer. It shouldn't even be aware of what the upper layers are going to do. If you've got a duplicate key error, then it should throw something like a "DuplicateKeyException". If you should hit an authorization error (I presume you mean "exception"), then don't do anything with it - let it bubble back up to the UI layer, which can display an appropriate error page.
Remember that error status values and such things are the reason we invented exceptions.
Enterprise library exception handling block is the bomb as many have pointed out. Using policies you can do things like logging the exception, wrapping it in a different exception, throwing a new exception instead of the original one. Also, if you are looking to perform specific actions based on authentication errors or duplicate record errors etc, you could always create specific derived exception classes and catch those exception types which would precludes the need of passing any objects from the top down. Exceptions should always bubble up not down.