I'm in the process of thrashing through the whole exception-handling jungle, and I'm now trying to determine just how many try/catch blocks I need, and where to put them.
From my controller I have
CreateInvitation(fromUser, toUser);
which calls down to my BLL method
public static Invitation CreateInvitaton(User fromUser, User toUser)
{
try
{// see if toUser exists, then create the invitation}
catch
{// throw something, maybe?}
}
Do I actually need to re-throw it in that method? Won't it go back up the stack even if I don't re-throw it?
Do I need to wrap the controller's call in a try/catch block too, or is that redundant?
Maybe I don't need the try/catch block in the BLL method at all, and only need a try/catch block in my controller?
I'm looking at quite a few possible combinations here, and have no idea what the proper one is.
Thanks.
The exception handler, as written in your example, is doing absolutely nothing. (well, it's wasting a little bit of time, but it's doing nothing of use)
Had it been:
try
{...}
catch
{
// do something here.
throw;
}
Then the try/catch & throw would be needed.
Catch exceptions locally if and only if they indicate exceptional behaviour and can be fixed (or commented) locally.
Hard enough to find an example - here's one: I have some objects which need pessimistic lock. The lock is needed because writing to the object from the web application while another (background) app is reading it could lead to disaster. It is truly an exception, because it will happen very rarely. Moreover, I can do nothing about it beforehand (because the lock might have been acquired just before the next line is executed). However, I can retry in a few msecs, because I know chances are good the object is released again. Still, all this does not happen in the controller, but in a service class.
Don't use exceptions for expected conditions (invalid input, for example).
Also, I agree most exceptions in web applications cannot be handled except for logging a message (which should not be done in the controllers) and sending an error page. Lastly, when catching exceptions, make sure to do it right (catch a specific exception type, retrow with throw; not throw ex;)
Related
I would like to return exceptions from a method, like this:
Exception f()
{
try
{
// Do something.
return null;
}
catch(Exception e)
{
return e;
}
}
I know that this is considered bad practice, but are there any technical reasons to avoid this?
EDIT: This is not the same question as Is it bad practice to return Exceptions from your methods. I am asking about technical reasons, not best practices.
There are no 'technical' reasons to avoid this. That is, the .Net framework will happily support this type of arrangement.
Also be aware that throwing exceptions incurs a performance penalty, so avoid relying on throwing exceptions for your normal control flow. They should only be used when something has genuinely gone wrong.
It's also fine to instantiate an exception without throwing it:
Exception f()
{
return new Exception("message");
}
Here are some reasons that you may want to rethink that design.
Firstly, new ArgumentOutOfRangeException(...); does not produce your exception stack trace is not generated until you throw it. This may confuse debugging efforts further down the stack. The stack trace will literally be lying.
Secondly, Exception is heavier than some sort of status enum to indicate what type of error occurred. It is hard to see what benefit you are getting out of the response object being of type exception. It presumably requires the caller to subsequently perform a bunch of if (response is FileNotFoundException) .... and decide what they want to do for each.
This means that you lose the ability to differentiate between expected exceptions and unexpected exceptions in a given function. Take a well understood unique constraint violation. Somewhere within your call, or something you call, an insert statement is rejected by the DBMS because of another record having this value. Depending on your use case, this is either an exceptional circumstance indicating something somewhere went very wrong (eg, a corrupt data file), or a result in its own right (eg, a booking system that allocated a seat to someone else between showing you its availability and you accepting). In the first case, you would want your caller to bubble that up to the point in the application which knows what to do about that. In the second, you can safely return that for the caller to do its business.
Thirdly, it is a violation of the principle of least astonishment. Exceptions, by design, are bail out by default. Unless I explicitly catch an exception, it will bail out of my method, excecuting the stuff in my except and finally blocks, nicely calling dispose for me at the end of any using blocks and repeat in my method's caller. What it will never do is execute the code of mine that might be relying on the results of that method call.
Your design here is ignore by default. Unless I explicitly check the result and choose to throw, it will carry on executing my code. Consider this contrived example:
Exception error;
error = GetData(out data);
if (error is DbException) return error;
if (error is ArgumentOutOfRangeException) return error;
// if (error is ....... etc
error = ApplyChangesToData(data);
// if (error is ....... etc
error = SaveData(data);
// if (error is ....... etc
Now the stakes are high if I miss something, because my partially constructed data object may then make its way through the ApplyChangesToData method and then get saved back to the database in corrupted form. This could be as simple as you not anticipating that internally GetData hits a SocketException or an OutOfMemoryException. It isn't just making your abstraction a bit leaky, it means that unless you do have a leaky abstraction, your code cannot be safely written. My code has to know whether you are talking to SqlServer or Oracle or Mongo or whatever so I can anticipate all the possible exceptions you may retun and include them in my if lines. Of course I could put an else in and throw any exception object, but presumably you don't want to do this or you wouldn't be catching it in the first place.
On the other hand, if you were allowing the exceptions to bubble up, and I was confident in what such an exception meant in my context and could still meaningfully carry on, I still have the option of catching that exception and reacting to or suppressing it.
The only exception (pun unintended) that I can think of is at the edge of an API service layer, where you might want to log the exception then return a generic "something went wrong on the server" rather than blab your dirty laundry and expose security sensitive information over a public facing endpoint.
I hope I have convinced you (or , if not, at least someone in the future reading this suggestion) not to go down that dragon-filled path.
I recently implemented a function which logs object contents using JSON.SerializeObject.
To cut a long story short, the idea was, that this function would be used in our newly implemented logging mechanism, to track objects when needed, based on system parameterization.
One absolute requirement for the entire logging mechanism, was that it should never throw exceptions, because it would be used extensively. Any developer should be able to use it and under no circumstances should this function cause any interruption in code flow. In case of failure, any call should simply be skipped.
After implementing it and having inspected and handled every exception that I could think of, I decided to wrap the entire functionality in an outer try-catch block, just in case.
Like so:
public static void TrackObject(object obj)
{
try { Console.WriteLine(JsonConvert.SerializeObject(obj)); }
catch { Console.WriteLine("Failed to track object."); }
}
After passing all tests with flying colors, I fired up the main application to do some actual environment testing.
To my surprise, due to a Nuget misconfiguration, my function caused an exception (System.IO.FileLoadException) after it was called, but before it entered the try-catch block and so it propagated back to the main application, causing havoc to code flow.
This got me thinking.
There are ways for exceptions to be thrown while calling the function but before a handler kicks in. There are also cases where an exception is simply unacceptable.
My current solution, was to create a wrapper function, which simply calls the actual function inside a try-catch. But this looks ugly and wrong. Plus I am not sure it is a bullet proof solution.
public static void TrackObject(object obj)
{
try { PrivateTrackObject(obj); }
catch { Console.WriteLine("Failed to track object."); }
}
private static void PrivateTrackObject(object obj)
{
Console.WriteLine(JsonConvert.SerializeObject(obj));
}
Is there a way to create a bullet-proof, no-way in hell, exception free method?
Or at least is there a definitive list of exceptions that can occur on a method call?
PS. The compiler warned me about the version mismatch, but I didn’t see it the first time.
PS2. I have created a sample project for anyone who wishes to see this issue in action.
https://drive.google.com/open?id=15BDrLNn87gsMHc9pQ-TgyDMSLQxDBq18
Is there a way to create a bullet-proof, no-way in hell, exception free method?
No. Even if the method is literally empty you can always have a thread abort exception thrown, or a stack overflow exception if there isn't enough space on the stack to call that method, or it could result in an out of memory exception.
is there a definitive list of exceptions that can occur on a method call?
If it's arbitrary code (i.e. from a delegate) then no. It could always be a custom exception of some type that didn't even exist when you wrote your code.
Also note that in your situation you need to be concerned about any possible exceptions that could be thrown in your catch block, if you just want to try handling normal exceptions (unlike the ones mentioned above) that happen in your try block. Just logging the exception could fail. In your example of using the console there could be problems with standard output that result in an exception. If you're really going for this code never throws you'd need to try to log the exceptions, but have other backup logging options for when they aren't working (and if you really can't throw, which as mentioned by others, is almost certainly a bad idea, then you need to be willing to go on without logging if logging your exceptions is failing).
What is the best practice for handling exceptions without having to put try/catch blocks everywhere?
I had the idea of creating a class that is devoted to receiving and handling exceptions, but I am wondering if its a good design idea. Such a class would receive an exception and then decide what to do with it depending on its type or error code, could even parse the stack trace for specific information, etc.
Here is the basic idea behind and implementation:
public class ExceptionHandler
{
public static void Handle(Exception e)
{
if (e.GetBaseException().GetType() == typeof(ArgumentException))
{
Console.WriteLine("You caught an ArgumentException.");
}
else
{
Console.WriteLine("You did not catch an exception.");
throw e; // re-throwing is the default behavior
}
}
}
public static class ExceptionThrower
{
public static void TriggerException(bool isTrigger)
{
if (isTrigger)
throw new ArgumentException("You threw an exception.");
else
Console.WriteLine("You did not throw an exception.");
}
}
class Program
{
static void Main(string[] args)
{
try
{
ExceptionThrower.TriggerException(true);
}
catch(Exception e)
{
ExceptionHandler.Handle(e);
}
Console.ReadLine();
}
}
I thought this would be an interesting endeavor because you would theoretically only need one or very few try / catch blocks around your main() method calls, and let the exception class handle everything else including re-throwing, handling, logging, whatever.
Thoughts?
There is actually a good reason why you don't see similar designs in production code.
First of all, such a design cannot help you reduce the count of try/catch pairs in your code (this should be obvious). It could help you reduce the number of catch statements for a given try, since you could just catch System.Exception and forward to the ExceptionHandler...
But what next?
Every exception needs to be handled differently. How would the ExceptionHandler know exactly what to do? You could try to solve this in a number of ways, e.g.:
Derive from ExceptionHandler and put the code to handle exceptions in virtual methods
Pass a number of Action<Exception> instances to the handler and have it invoke the proper one
Solution (1) would be worse than what you had before: now you need to create a whole new class for each try block and override a bunch of methods to end up with something worse than you had before (it's not immediately clear how the code in a particular class fits in the flow of your program). It would also leave another important question unanswered: you may need context (access to variables in the current scope) to properly handle the exception. How will you provide access to this context?
Solution (2) would actually end up quite similar to writing the catch blocks that we 've been wanting to avoid (each Action would be effectively the contents of a catch block). We end up doing the same thing, only in a more complicated and verbose manner.
There are also other issues:
What should ExceptionHandler do if it cannot handle the exception? Throwing it again will cause you to lose the original stack trace, in effect destroying all the good information in there.
What if there's a bug in ExceptionHandler? You can truse a try/catch. Can you trust code you wrote yourself to the same degree?
As for the ExceptionThrower... what benefit could it possibly offer over throw new Exception();?
Exception handling is a complicated matter already, and it's difficult enough to get it right without adding extra gears to the machine. Especially if they don't buy you anything new. Don't do it.
OK, this is probably not the answer you want but...
I am generally allergic towards the idea of a general exception handling class. You can almost hear how it is a contradiction in itself. An exception is an exceptional event. Exceptional events cannot be handled in a general manner, but needs tailored handling wherever they may appear, which essentially means that your code should to two things:
be defensive about any input in order to avoid exceptions in the first place
put try..catch blocks wherever it makes sense to catch and handle an exception (note that this means that you should not have try..catch blocks in all methods)
So, where does it make sense to catch and handle an exception? In short, where your code has knowledge that makes it capable of handling the exception. If it does not, let the exception bubble upwards to the caller. The only place where I think you should catch all exceptions and have some generic default behavior around what to do, it at the top level of your app. That is typically the UI.
Sorry, this is not a good idea. When you catch an exception in your code with a normal try/catch block surrounding the relevant section, you get to use two critical pieces of information to deal with the problem: the type of exception, and also where the exception occured.
With your arrangement, you have to deal with all exceptions knowing only what type of exceptions they are. You no longer know where the exception actually occured, so you really can't do anything about the problem other than to log it or show a message to the user.
Moreover, try/catch blocks often also include a finally block, in which you can make sure things happen even if an exception is thrown (like closing streams etc.). You don't have any way in your arrangement of dealing with this.
Proper exception handling can be tricky, and there is no magic bullet that will make it simple and straightforward. If there were, .Net would have already incorporated it.
We have a class in our code-base that has a pretty similar signature to the one you have proposed and I can tell you now that it has only bough misery and suffering!
Why do you have so many try-catch blocks in your code? Can you give some examples? Exceptions by their very nature "Exceptional", i.e.not that frequent! Not only should you not be catching exceptions that frequently, but also every exception is different and the same boilerplate code that works in one situation probably isn't suitable in many other situations.
Nobody said that exception handling was easy (or produced compact code) - you should think carefully about each situation you need to catch an exception and handle it appropriately - avoid catching exceptions that you don't need to handle.
I am working on application where user invokes a method from UI , on this I am calling a method from business class which calls another methods
UI--> Method1 -->Method2 --> Method3
I want to display the error message to user if any exception occurs in any of the method.
Shall I go with throwing the exception directly to the caller method and at the UI layer I will catch exception and display the message.
Apart from Throwing exceptions and catching it at caller is there any better way to handle it?
I do not want to use the C++ convention where integer is returned as the result.
If you can't recover from the exception in the method where the exception happens, don't try to catch it (unless you want to log it, in which case throw it again after logging). Then catch at the UI-level.
Trying to catch exceptions at every level just adds bloat to your code.
Given your example of UI--> Method1 -->Method2 --> Method3, I would make sure that the UI has a try/catch, but then none of the other methods should catch exceptions unless they can handle them without re-throwing. And even if they handle the exception, you should question whether that exception should happen in the first place. If you handle an exception and go about your merry way, then that exception is part of your normal process flow which is a serious code smell.
Here are my recommendations:
1) Put your exception handling code in all your UI events, and then have the actual action farmed off to some other method. Don't scatter exception handling code all over the place. It's clunky and makes the code hard to read.
protected void Button1_Click(object sender, EventArgs e) {
try {
DoSomething();
}
catch Exception e {
HandleError(e);
}
}
2) Don't do this. You'll lose your stack trace and the next developer who maintains your code will hunt you down.
try {
DoSomething();
}
catch Exception e {
throw e; // don't rethrow!!!
}
If you aren't going to handle the exception, don't catch it. Or, use a naked throw like this:
try {
DoSomething();
}
catch SomeException e {
HandleException(e);
}
catch {
throw ; // keep my stack trace.
}
3) Only throw exceptions in exceptional circumstances. Don't have try/catch blocks as part of your normal process flow.
4) If you're going to throw an exception, don't ever throw a System.Exception. Derive an exception object and throw it. I often just a generic BusinessException class. This way, users of your code can determine what exceptions you made up and which ones are system/environment related.
5) Throw ArgumentException, ArgumentNullException, or ArgumentOutOfRangeException if a method caller violates the contract (preconditions) of your method. If you catch one of these, it's a programming bug. A user should never see these exceptions.
If you remember that exceptions should be a very rare occurrence and that handling them is almost always a UI concern (so the bulk of your try/catch code should stay at the UI level) you will do well.
The basic rule is "Don't catch exceptions when you cannot handle it." So any unexpected exception should ultimately tell the user that something went wrong and shut down the application as gracefully as possible. Not shutting down the application is risky because the state might be corrupted and in turn corrupt information important to the user.
Robust applications are modular so that the application can recover without shutting down by stopping or restarting single components like services or plugins.
There are some cases where you might want to catch exceptions that you cannot handle but then the exception should either be re-thrown or a new exception should be thrown.
If you want to log exceptions you will catch, log and re-throw.
If you want to improve the error message you will catch, wrap in a new exception, and throw. For example you may want to wrap a generic FileNotFoundException when reading a file in a new exception with a more descriptive message telling the user what file could not be found.
Whatever you decide - be consistent. 30 days from now yourself (or another developer) will need to understand your code.
Also, as Scott Hanselman likes to quote on his podcast (and I think it might be in the Beautiful Code book) -
All problems in computer science can be solved by another level of indirection," is a famous quote attributed to Butler Lampson, the scientist who in 1972 envisioned the modern personal computer.
Throwing exceptions is expensive. And I like to have my business layer have its own specialized exception that only it can throw. That way it makes it easier to track it down. For example (off the top of my head since I do not have a C# compiler in front of me):
public class MyException : Exception
{
private MyException(Exception ex, string msg) {
this.Message = msg;
this.InnerException = ex;
}
internal static MyException GetSomethingBadHappened(Exception ex, string someInfo) {
return new MyException(ex, someInfo);
}
}
As a rule of thumb, exceptions should only be used for exceptional cases. That is, if you expect a method call to fail sometimes, you shouldn't use exceptions. If there are several possible outcomes, you could use an enumeration:
public enum AddCustomerResult
{
Success,
CustomerAlreadyExists,
CustomerPreviouslyRetired
}
You'd still get exceptions thrown, for database-unavailable errors, and the like; but you'd be testing for expected (albeit possibly rare) cases and indicating success/failure/etc as required.
This is just one technique that works well for me.
With exceptions you want to throw them in exceptional circumstances and anywhere where there is a layer traversal (my own convention, don't know how correct it is) you'd want to catch exceptions and rethrow with a custom wrapper class for that layer.
For example, in the DAL you'd want to catch exceptions and rethrow them as an inner exception on a DataAccessException perhaps; on a web service you'd wrap all your methods in exception handlers to rethrow with a MyWebServiceException. At the UI (which traverses the from inside the app to the user's screen) you'd want to catch, log and give them a nice message. As far as I can see no reason to catch or rethrow anywhere else.
It gives you an opportunity to hide the underlying exception (which you likely don't want to expose to the caller: e.g. database errors), log in centrally, and provide a common repeatable failure mode.
In your example, you'd catch exceptions at the UI level only; because if a UI operation fails you don't want the app to crash out with an unhandled exception.
Hope that helps!
When you design a multi-tier application, you should keep in mind that those tiers can be distributed, maybe hosted within different services on different machines, thus making it necessary to throw exceptions through remote boundaries which is not a very preferable way to do.
In such a case, catching them and just bubbling some sort of error message or code is a better way in my opinion. Additionally you should allways trace the exception when you catch it. Its always good to know whats going on in your application.
It almost always pays to separate exception handling and error reporting.
Catch exceptions where it makes sense to catch them, where you have enough context to know what exactly happened and how to recover - inside Method1..3. On catching known exception, push a record to the error log.
After completing operation or step UI level can check error log and present message of "Following errors occurred: ...".
When writing a C# application whose #1 priority is to never crash, how often should I used a try-catch block?
Can I encapsulate all the statements in a method in try-catch blocks?
public void SomeMethod()
{
try
{
// entire contents of the function
// library calls
// function calls
// variable initialization .. etc
}
catch (Exception e)
{
// recover
}
}
What are the downsides to wrapping everything in try-catch blocks?
The only down side is when an exception is actually thrown. There is no overhead for wrapping the code, except for when exceptions occur.
Also, you don't want to use try/catch for control flow. Consider this (bad code):
try {
FileStream fs = File.Open("somefile.txt", FileMode.Open);
} catch (Exception ex) {
MessageBox.Show("The file does not exist. Please select another file");
}
You'll get more performance from some thing like File.Exists. such as:
if(!File.Exists("somefile.txt"))
MessageBox.Show("The file does not exist.")
EDIT:
found the MSDN direct quote:
Finding and designing away
exception-heavy code can result in a
decent perf win. Bear in mind that
this has nothing to do with try/catch
blocks: you only incur the cost when
the actual exception is thrown. You
can use as many try/catch blocks as
you want. Using exceptions
gratuitously is where you lose
performance. For example, you should
stay away from things like using
exceptions for control flow.
This is a big topic. Start here for some excellent discussion of Exception handling best practices and be prepared for a religious war...
Code Analysis Team Blog
Martin Fowler - Fail Fast
MSDN on Exception Handling
Checked vs Unchecked Exceptions
My own opinion is that for the most part you use "try/finally" a lot, but "catch" very little. The problem is that if you attempt to catch and handle Exceptions in the wrong instances, you may inadvertently put your application in a bad state. As a rule, use dev and test to learn where you actually need to handle an exception. Those will be places that you can't check. i.e. you shouldn't really need to handle nullreference or filenotfound because you can proactively check for those. Only exceptions you know may happen, but you can't do anything about. Beyond that, for the sake of your data's state, let it crash.
If you are swallowing exceptions, it generally means you don't understand your program or why you are getting an exception. Catching System.Exception is the poster child of code smells...
Actually, I very rarely use a catch block except for logging purposes. finally is much more common for me. Most times, lock or using do everything I can usefully do (and indeed, that is a finally also).
Eric Lippert has a blog entry on exceptions that may be useful.
The key to this question is the following line:
// recover
To be able to recover, you have to know what and how to recover. And that's assuming it is possible to recover, which quite frequently it isn't.
You should only use the catch part of try/catch/finally to swallow an exception when you know how to handle the exception, when you know how to recover from it, and when you're sure you can do so without leaving the application in an inconsistent or invalid state.
If you can do this for all possible exceptions in all method calls in your application then go right ahead, otherwise you might need to re-think your #1 priority (sometimes failing fast is a better options than trying to keep an application alive when something has gone wrong, and having a much harder to debug crash later on).
Generally IMO it is better to put smaller chunks that are out of your control in a try catch. If you say:
try
{
//anything that could possibly go wrong
//This kind of thing is only good for Logging IMO and could be done in
//Global.asax
}
How could you possibly know what to do in your catch method cause it could be anything...
Its much better to go:
try
{
//divide user imputs
}
catch(DivideByZeroException)
{
// tell user bad inputs ect....
}
catch (Exception e)
{
//If you choose to throw the exception you should
//***********************
throw;
//VS
throw ex; //Throw ex will restart the stack trace
// recover
}
finally
{
//Clean up resources and continue
}
In which finally is always run
There is performance overhead for try blocks, if you do that your entire function will run slower then it otherwise would. catch (Exception e) is also a bad idea, if you catch you want to do something useful with what you caught, and if you catch all exceptions it is impossible to know what you should be doing.
You can do this, although almost in any given environment you're running in, there's a global exception handler where you can catch and handle even unknown errors.
For web apps, there's the Global.asax, for a console program, just wrap your Main() in a try/catch, for services, there's AppDomain.CurrentDomain.UnhandledException, etc.
You should wrap sections where you can predict what the exception might be in more specific blocks, but the global exception handlers should greatly simplify your code and help you out.
You should only catch and stop the exception without rethrowing it if you can meaningfully handle it. Otherwise it is an error and it should propagate up.
I assume that when they say "this app should never crash" there is an implicit requirement that it behaves correctly. Only stoping exceptions that are meaningfully handled satisfies the behaving correctly requirement.
Typically an app will have a single top-level catch block to catch and log unhandled exceptions. These should occur infrequently (and perhaps your requirement can be interpreted to mean these should not happen at all). If you catch and stop exceptions anywhere else in your code, you risk not discovering these problems. If you catch log and stop in lots of other parts of your code, you have a poorly constructed app from the perspective of separation-of-concerns.
I try to avoid try catch blocks generally. I prefer to use blocks to force the user into obeying the rules of an application. For example, if a user should only enter an int that is equal to or less than an int x I'd use:
if (input > x)
{
Console.WriteLine("Invalid input. Please enter a number that is equal to or less than x.");
{...}
}
rather than using:
catch (IndexOutOfRangeException)
{
//error message here
}
From my own personal experience I find it easier to write as you can avoid encapsulating code in a try block (guarding code).
Of course, there will always be times where using try catch is unavoidable - I just like to work around it where possible.
Our current application has a similar mandate: Never crash. Always back out gracefully. To do this, you have to make sure that every line of code is either enclosed in a try-catch block or only called by code that its exceptions can bubble up into.
Also, to protect against uncaught exceptions, we attach an UnhandledExceptionEventHandler to AppDomain.CurrentDomain.
You should use them anytime a piece of code can thrown an exception.
You have to be careful, catching general exceptions is never a good idea. You have to decide which layer you want to handle them.
Meaning the deeper you are you want to catch very specific excpetion and go more general. In a database catch the SqlException. As you go higher in the stack you catch more exceptions to finally catching the general exception at the very top.
That way you can deal with each exception on a case by case basis. A general exception you aren't going to know what to do with.
public void functionName
{
try
{
//your codes
//sometimes 'return' shows exceptions
}
catch(Exception e)
{
messagebox.show(e.Tostring()); //to know what is the exception
}
finally
{
}
}
try catch in c#:
try{
}
catch (NullReferenceException en)
{
}