Throwing nested Exceptions from a catch block...is this wise? - c#

I want to implement custom exception handling in my library so that I know where an exception occurred, so I am doing this:
try
{
DoSomething();
}
catch(Exception ex)
{
//LibraryException refers to any exception in the libraries exception hierarchy
throw new LibraryException(ex.Message, ex);
}
Should this be avoided?
Does it have any performance implications?
What are the implications of catching, nesting and re-throwing exceptions?

The only potential problem is that you're catching a non-specific Exception, so not conforming to the exception handling guidelines.
One of the following would be more conformant with these guidelines:
try
{
DoSomething();
}
catch(SomeException ex)
{
throw new LibraryException(ex.Message, ex);
}
or:
try
{
DoSomething();
}
catch(Exception ex)
{
if (ex is SomeException || ex is SomeOtherException)
{
throw new LibraryException(ex.Message, ex);
}
throw;
}
As for performance, once an Exception has been thrown, something exceptional has happened, and you probably don't care about the small additional overhead of wrapping it.
From comments:
in most cases when a library chooses to wrap exceptions it will wrap all exceptions that are thrown outside of the scope of the library, ...
I disagree with this, though it's admittedly subjective. One example of a library that wraps exceptions is SqlMembershipProvider, which wraps some specific exceptions in a ProviderException, e.g.:
try
{
new Regex(this._PasswordStrengthRegularExpression);
}
catch (ArgumentException exception)
{
throw new ProviderException(exception.Message, exception);
}
but other exceptions such as SqlException that a caller can't be expected to handle are propagated unwrapped.

This is a good practice, if it adds abstraction and/or clarity to your architecture.
It makes the exception more explicit, and may hide lower-layer details from higher layers. For instance, in a Data Access Layer you may catch SqlExceptions and throw DataAccessExceptions instead, so that the higher layers do not "know" you are using SQL Server as your data store.

Should this be avoided?
That's a matter of preference. In some situations it can be advantageous, in some detrimental, and in most cases some of both. There are cases where you see this done by existing libraries, and there are other libraries that choose not to.
Does it have any performance implications?
Probably, yes, but I doubt it's real significant. It's not exactly cheap to begin with.
What are the implications of catching, nesting and re-throwing exceptions?
advantages:
Someone calling your method can easily catch exceptions thrown from your library.
Hides implementation details of your library from the caller.
Allows the caller to easily catch exceptions just from your library. Without this if they try to catch, say, an invalid argument exception it could come from either your library or their other code. They may want to only catch argument exceptions thrown from other places.
disadvantages:
It's harder to catch just one of the types of exceptions that may have been thrown from your library while not catching others.
It adds a lot of clutter to the exception text when it is displayed.

In context, throwing a more specific exception is generally a good idea, provided that LibraryException comes from your own problem domain and provides more specific information to a developer such that they can say "Ah, a Library exception means that one of a certain class of errors occurred."
try-catches do impose their own performance overhead, but I see nothing that makes this block substantially worse than any other similar block.

Ok, so as a real quick overview, when an exception is caught in a try catch block, it has to gather then entire stack for the trace. Throwing any type of exception is actually rather expensive, but it gets exponentially so when you nest throws inside of catch blocks. So really you should only throw an exception if you know exactly why you are throwing it and plan on handling it through a try. This is mostly the case when you are creating an API, and cannot predict how another developer may use your library.
If you are writing for your own application, you should avoid throwing an exception at all, since you are just throwing it to yourself (basically). In that case, you should be handling what happens if an exception is thrown not throw your own.
Unlike Python (which I like but different paradigm) and other "oops" languages, it is not good practice to control flow through exception handling in C#.
Under C# how much of a performance hit is a try, throw and catch block
Arguments for or against using try catch as logical operators
Exception Handling in C#
C# Exception (Check this one out)
CA1031: Do not catch general exceptions

Related

What are exceptions and why "throw" them?

I've read many sites and other responses on StackOverflow, but I still haven't grasped the the importance of exception handling and why we "throw" them.
For this post, my understanding of an exception can best be described as:
"An exception is a problem that arises during the execution of a program. A C# exception is a response to an exceptional circumstance that arises while a program is running..." https://www.tutorialspoint.com/csharp/csharp_exception_handling.htm
When handling exceptions, I often see the following code snipets:
try
{
// Do something that causes an Exception
}
catch (Exception)
{
// Could have error logging here
throw;
}
If you do not perform any error logging, why have the "try/catch" and "throw" statement? The code will still throw an exception regardless of whether I try/catch. I must be missing something. What does "throwing" do?
I've included a basic divide by zero scenario in the following:
https://repl.it/BjgV/24. When you remove the "try/catch/throw" you see the same results.
Something to keep in mind is not only that caught exceptions can be used for logging errors, they can be used for handling errors that might arise.
Let's say you have some kind of Widget object, that has properties you initialize via arguments to a constructor:
public class Widget
{
public string Name;
Widget(string widgetName)
{
if (widgetName != "")
Name = widgetName;
else
throw new ArgumentException("Name must be provided for widget.");
}
}
In this case, we have a situation where we want to require our Widget have a name when it's instantiated - we check the argument to see if it's blank, and we throw an ArgumentException to indicate that something is wrong with one of the arguments to the constructor, as well as include a helpful message about what specifically went wrong.
This means we can then have context-specific validation logic in a wrapper, rather than having to have everything crammed into our base Widget class:
public Widget ForCaseA (string widgetName)
{
Widget w;
try {
w = new Widget(widgetname);
}
catch (ArgumentException as argEx) // We're specifically catching the subtype of ArgumentExceptions; generic Exceptions or other types of exception wouldn't be caught here and would bubble up out of this try/catch block.
{
// At this point, we could look at the specific data in the exception object to determine what needs to happen to resolve the exception. Since there's only one argument and it's throwing an ArgumentException, we know it's going to be a problem with a bad widgetName. In this case, we can say 'well, in this specific case, we want to give it a default widget name'.
w = new Widget("DefaultName");
}
return w;
}
One of the ways catching exceptions by type becomes exceptionally useful is when you use inheritance to create your own types based off the generic Exception class; e.g. giving your Widgets a WidgetException. This lets you catch issues specific to your class/entity (like the widget's name), but doesn't have to handle issues that fall outside the scope of the Widget itself.
"Throwing" is sometimes (in non-oop languages) the same as "raising" an error.
If we catch an exception, we might want to bubble that up to some method higher in the callstack, and perhaps generalize it more in the process. Thus, we might use something like:
try { doSomething(); }
catch (VerySpecificException ex) {
throw new SomeGenericException(ex);
}
This allows us to expect only generic exceptions in the higher-level programming, while maintaining a full stack trace and inner exceptions so we can see where it came from.
Throw, on it's own (such as in your example), simply pushes the error up to the next caller, with no changes. In your exact example, you might just leave out the try/catch altogether, as the result will be the same (the exception gets pushed to the next block: excepting maybe if you have some AOP or weaving in there to handle it, but that's a bit beyond this answer I think).
If there's no try/catch block, the exception is pushed back up to the next method in the callstack. If there's no try/catch blocks anywhere, the exception is said to be "unhandled", and your application crashes. There's no excuse for an unhandled exception to make it to the top.
Specifically regarding this part:
If you do not perform any error logging, why have the "try/catch" and "throw" statement?
Aside from logging the exception, in some situations you may want to:
Wrap the exception in a meaningful user-defined exception which you throw to raise some error.
Release certain resources just in case the exception happens and bubble it up for potential handling somewhere else.
These are just two examples.

Why does the C# compiler authorize "throw ex" in catch, and is there a case where "throw ex" is useful?

In C#, younger developers use often "throw ex" instead of "throw" to throw exception to parent method.
Example :
try
{
// do stuff that can fail
}
catch (Exception ex)
{
// do stuff
throw ex;
}
"throw ex" is a bad practise because the stack trace is truncated below the method that failed. So it's more difficult to debug code. So the code must be :
try
{
// do stuff that can fail
}
catch (Exception ex)
{
// do stuff
throw;
}
My question is why compilator authorize this (or doesn't display a warning message ?) Is there a case which "throw ex" is useful ?
Is there a case which "throw ex" is useful ?
Sure - sometimes you want to truncate the stack trace - to avoid exposing implementation details, etc. Other times you may want to throw a new exception, which would mean the compiler would have to distinguish from just re-throwing the caught exception and throwing a new exception.
So why would you want the compiler to prevent you form doing something that 1) is not illegal and 2) could be useful?
throw new Exception(); or throw ex; both will use the same language rules to allow throwing an exception object, (whether new or existing). When you want to add some extra information with the exception than that option is helpful.
See: How to: Explicitly Throw Exceptions - MSDN
You can explicitly throw an exception using the throw statement. You
can also throw a caught exception again using the throw statement.
It is good coding practice to add information to an exception that is re-thrown to provide more information when debugging.
Since both, throw new Exception() and throw ex; would require the same language rules, it is not really compiler's job to distinguish those two.
Simply throwing the existing exception without any modification to the exception object would be using the same language construct.
Also as #D Stanley has pointed out in his answer, that truncating the stack trace could be the desired behaviour.
As far as your question about compiler not warning about it is concerned, It is not the job of compiler to warn about bad practices, there are code analysis tools. For example Managed Code Analysis tool will raise the warning for throw ex; CA2200: Rethrow to preserve stack details
While compilers can certainly prevent some obvious programming errors, they cannot possibly watch out for best practices like that without triggering some inevitable false positives along the way.
Programmers could choose to change the content of the exception inside the exception handler, or throw a brand-new exception instead. In both cases a message that warns about throwing an exception from an exception handler would be annoying and useless.
One case when it make sense to change the internal state of an exception happens when you throw an exception from a recursive function. Consider a recursive descent parser reporting an error from several layers down the recursive chain. Each level of invocation could potentially add more useful information to an exception. However, wrapping exceptions of each subsequent layer into a new exception is not practical in this case, because you end up with a recursive data structure representing a flat list. One viable solution for situations like this would be creating a custom exception to which each catcher can add more details before re-throwing it. Since the function (or more precisely, a group of functions) is recursive, the location in code from which the original exception has been thrown is of less importance than the completeness of the context that lead to the exception in the first place.
It does not mean that finding situations like that is entirely useless: code proofing tools, such as ReSharper, can certainly help programmers watch out for issues like this. The compiler, however, is a poor choice for a best practice watchdog, because for the most part the compiler should do what it is told.
I guess I consider catch the culprit when you actually just want something to propagate up the stack. Shouldn't catch be avoided entirely in favor of finally?
bool bSucceeded = false;
try
{
// do stuff that can fail
bSucceeded = true;
}
finally
{
if( !bSucceeded )
// do stuff you need to do only on error. (rare, for me)
// cleanup stuff (you're nearly always doing this anyways right?)
}
I've written many bSucceded's, and don't think I have ever written throw inside catch without wrapping in a new Exception(). (At least since I was first learning Java in '99 or so.)
I'm guessing the massive number of possible ways to deal with this is why they let you do what you want here instead of trying to lock it down.

Exception issue

All the time, to avoid any run time error, I use the Exception handler:
as the following:
try
{
//My code which may raise an error.
}
catch (Exception ee)
{
string message = ee.Message;
ShowMessage();
}
My question is:
Is this considered as a good practice or bad practice? (I use the same
lines all the time)
What about the performance issue every time declaring a string?
When using those lines with a method which return a value, the
returning must be after the catch?
That's bad code. Actually very bad.
As all you do with the error message is to assign it to a string that you never use, you are effectively just catching the exception and ignoring it. This is pretty much the worst thing that you can do with an exception, as the program will continue on as if nothing happened, likely with unusable or corrupted data.
When catching exceptions:
Use a more specific Exception type, for example SqlException or IOException, so that you only capture the exceptions that you intend to catch, and that you know how to handle.
When catching an exception, either really handle it, or rethrow it so that it can be handled at a different level.
You should handle known issues first to improve performance, such as null references, empty strings, etc.
Use exceptions for exceptional cases.
Declaring the string isn't a bad thing in there, but its not doing anything other than holding another reference.
You can safely return from a try block. But as Damokles states, you should also have another return else where.
The general structure of exception handling is the following:
try
{
//do struff here
}
catch (...)
{
//handle exception here
}
finally
{
//clean up here
}
There are a couple of things to note in your code that are not entirely right (they are terrible in fact :p):
Only catch exceptions you are ready to handle and do not handle those you are not. This means that you should only catch particular exceptions (FileNotFoundException, ArgumentOutOfRangeException, whatever) that you know can happen in exceptional cases (never use exception handling as a normal execution flow tool). Catching System.Exception is considered bad practice (unless it is for logging purposes and you throw; immeadiately afterwards) because this exception can be thrown by any darn thing, which with all probability you have not foreseen when writing your code and therefore have no clue on how to handle it correctly.
Depending on your situation you should consider using finally blocks in order to clean up whatever you can before exiting the method (be it because of normal execution flow, or an unhandled exception). Note that finally blocks will be (normally) always executed before exiting the method scope.
Do not swallow exceptions and the information they contain. You should consider logging it somewhere (myApplication.log file) and show the user a more friendly "we have aproblem" message. Otherwise the only information you will have when bugs crop up in production will be whatever you show the user. All the valuable information stored in the caught exception will be lost.
There is no need to add exception handler in all the functions. Add the exception handling at the main() which wraps all the functions. Only add exceptions handlers at place where you intend to do some specific exception handling operation to prevent the application from crash.
Return value can be added in the try block.
I assume you are doing this to IGNORE exceptions? In that case you can do it like this:
try
{
// code
}
catch {}
This will catch all exceptions and do nothing with them(ignore).
I would however not recommend doing that, because you will now never know why some functionality in your system is not working as expected because no errors are thrown. I would then recommend at the minimum at least LOG the exception so that you can troubleshoot problems later. A better approach would be to log the exception and re-throw it and then have friendly exception handling at the UI layer.
This is considered a bad practice as you basically ignore the exception. You don't even show it to the user!
It's even double bad, because it is also a bad practice to copy-paste the same lines all over your code.
Recommended usage is to either handle the exception, or do not touch it at all. As it's rather uncommon that the code knows how to handle an exception, the common case is to not catch it at all!
Of course, way up in your main loop, you'll have a try-catch, which will log the exception and/or report the exception to the user.
With respect to your second question: Yes, a return statement can be part of the catch block. But if you don't know what to return, you should not catch the exception!
You should only catch exceptions that you are expecting and know how to handle them. by catch (Exception) you are catching all kind of exceptions in a method is not a good practice.
You can catch all exceptions to just log them or restart you application on fail..
For example
try
{
//My code which may raise an error.
}
catch (FileNotFoundException)//you are expecting this exception
{
//handle file not found here.
}
catch (Exception ee)
{
string message = ee.Message;
Log(message);
throw;//rethrow the exception
}

C# - Rethrow an exception without setting it to an variable

As all of you probably know, catching and re-throwing a exception in c# this way is evil, because it destroys the stack trace:
try
{
if(dummy)
throw new DummyException();
}
catch (DummyException ex)
{
throw ex;
}
The right way to re-throw an exception without loosing the stack trace is this:
try
{
if(dummy)
throw new DummyException();
}
catch (DummyException ex)
{
throw;
}
The only problem with this is that I get a lot of compilation warnings: "The variable 'ex' is declared but never used". If you have a lot of these, a useful warning may be hidden in the garbage. So, that's what I did:
try
{
if(dummy)
throw new DummyException();
}
catch (DummyException)
{
throw;
}
catch(AnotherException ex)
{
//handle it
}
This seems to work, but I'd like to know if there is any downside of re-throwing an exception that is not set to an variable. How does .net threats this?
Thanks in advance
Edit:
I've changed my code a little bit to make clearer what I wanted to do, as some had misunderstood
I'd like to know if there is any downside of re-throwing an exception that is not set to an variable.
No, there's no downside at all. A variable is only needed if you want to reference the exception in your code, but since you don't need to do that with a throw statement, you don't need a variable at all.
And you have exactly the right idea in attempting to eliminate "noisy" compiler warnings. They have a tendency to bury important errors that you do want to fix, and getting a clean build is always important. The best solution is simply to rewrite the code to use a parameterless catch clause.
However, be aware that in 82% of cases that I see*, it's a mistake to write code that uses throw at all. You generally shouldn't catch exceptions that you don't know how to handle and your only intended "handling" strategy is to rethrow them. There are cases where even using throw can reset the call stack, causing you to lose important debugging information. There are also better alternatives for logging exceptions to catching/rethrowing. You can find more information in the answers to these questions:
Main method code entirely inside try/catch: Is it bad practice?
what can lead throw to reset a callstack (I'm using "throw", not "throw ex")
There's absolutely nothing wrong with letting exceptions bubble up and handling them all in a central place. The rule to keep in mind is that you shouldn't use exceptions for flow control. But there's nothing wrong with throwing an exception in low level code, and showing the user an error message higher up the stack in UI code. Read Microsoft's Best Practices for Handling Exceptions for some general tips.
* Slightly more than the percent of statistics that are made up on the spot.
There is no downside to that. You are simply telling the compiler "I plan to catch this exception but I have no need for a reference to the actual exception", it doesn't affect how things are thrown or how exceptions work. Your latter example is the ideal way to do what you want, however if you are merely going to immediately throw; with nothing else whatsoever in the block, then why catch at all?
If you're not doing anything with DummyException in the catch block (which you can't, since you haven't given it an identifier), why not get rid of the try/catch block entirely? E.g., just do this:
throw new DummyException();
Although at that point, I'd probably evaluate what you're trying to accomplish here and rethink your application architecture so as not to not rely on exception propagation in this manner.
Why catch if your simply going to re-throw? Anyway, you may want to take a look at this previous discussion. Though not identical much of what is discussed is relevant:
Throw VS rethrow : same result?
Actually throwing an exception using "throw;" is a .Net best practice, because it preserves exception stack trace.
Throwing exceptions using "throw ex;" is considered a worst practice, because it looses the original stack trace and should be avoided.
Why catch and rethrow like this? Why do people always have to assume they know every case? Answer: Database transactions.
If you have a better way to do this please speak up Dr. Proton, no offense taken. Keep in mind that there are a lot of different database systems in use but most of them support transaction control (begin/commit/rollback) and have C# interfaces.
pseudocode (a simplified case):
try
{
db.beginTrans();
db.doStuff();
db.doOtherStuff();
db.commitTrans();
}
catch
{
db.rollbackTrans();
throw;
}
Now, it is quite annoying to lose the detail of whether doStuff() or doOtherStuff() failed and I don't see any good reason why C# would toss the line number information in this case. But it seems to. Hence the googling and my subsequent arrival. If I am missing something please do tell.

Catch Exception with Condition

Note: I am very happy to tell you that exception filters are now in the C# 6.0 language.
This is a thought experiment, I'm interested in your opinion: Does it make sense to you? Do you know whether something similar has already been proposed for the C# programming language? I wouldn't even know where to send such a proposal...
The idea is introducing syntax elements to catch an Exception only if it fulfills a certain condition.
One use case example is when working with COM Interop: Everything always throws a COMException. The actual distinguishing error code is contained in its message.
So what about (proposal 1):
try
{
...
}
catch (COMException ex where ex.Message.Contains("0x800706BA"))
{
// RPC server unavailable
}
catch (COMException ex where ex.Message.Contains("0x80010001"))
{
// Call rejected by callee
}
which translates to:
try
{
...
}
catch (COMException ex)
{
if (ex.Message.Contains("0x800706BA"))
{
// RPC server unavailable
}
else if (ex.Message.Contains("0x80010001"))
{
// Call rejected by callee
}
else
{
throw;
}
}
Similar cases are: SoapException, XmlException...
Another scenario is when exceptions are wrapped as inner exceptions within a general exception, and the catching logic should depend on the inner exception.
Say we have an API that wraps exceptions like this: catch (NumberFormatException ex) { throw new BusinessException(ex) }.
What about (proposal 2A):
try
{
...
}
catch (inner NumberFormatException nfex)
{
...
}
which translates to:
catch (Exception ex where ex.InnerException is NumberFormatException)
{
NumberFormatException nfex = ex.InnerException;
...
}
or (2B):
catch (BusinessException bex inner NumberFormatException nfex)
{
...
}
which translates to:
catch (BusinessException bex where bex.InnerException is NumberFormatException)
{
NumberFormatException nfex = bex.InnerException;
...
}
In this case (originally from Java) it could look like (2C):
catch (RemoteAccessException raex inner inner MyException mex)
{
...
}
According to the try-catch C# Reference for Visual Studio 2015 RC this is now implemented:
Catch (ArgumentException e) when (e.ParamName == "…")
{
}
VB.Net has this feature of exception filter as shown below
Catch ex As COMException When ex.ErrorCode = 0x800706BA
So this is supported by the CLR but the feature is not exposed in C#
Supposedly F# has this feature as well but I don't know much about F# to show example.
Exceptions and types are tightly related. If you want to distinguish between two separate kinds of exceptions, you should make two exception types. In your example, you would have a Com800706BAException and a Com80010001Exception.
Now, this is not always possible or feasible, for example if the underlying system uses error codes instead of exceptions. In that case, your method may be helpful. However, this language feature would easily be misused. For example, you could do error handling like this, which is not type-safe:
catch (Exception e where e.Message = "The foo barfed up the bar")
If you want to check the inner exception of an exception, you are doing the error handling on the wrong level. The idea is that a method throws a generalized exception to abstract the caller from the inner working of the method. If you depend on some inner exception, you are tightly coupled to the implementation of the method. This is bad.
Either a separate, generalized exception should be thrown, or the error handling should be moved inside the method.
Why bake something into the language that is trivial to do anyway?
Proposal 1 is easily addressed with a targetted switch statement inside the catch - that way you can deal with the COM exceptions that you want and just rethrow anything you don't want to deal with.
The problem with Proposal 2 is that the exception stack could be arbitrarily deep, and could (or will) contain:
multiple nested instances of the same type of exception - which one should your query syntax deal with?
different exceptions which derive from the same base exception* - if your query syntax specifies one of the lower level base exceptions then that could match a whole bunch of higher level exceptions in the stack, which one(s) are you looking to process?
Most of the time when you are iterating the exception stack you won't be interested in retrieving the exception that is halfway down the stack, instead you will walk the exception stack and get the very first one for logging purposes. The rest of the time you only care about the last (outer) exception. I personally cannot recall a time where i had a need to programmatically catch/handle an exception that was buried somewhere in the middle of the stack, it has always been first, last, or all of them.
*disregarding the fact that all exceptions derive from System.Exception - i was meaning more along the lines of MyBaseException which all your custom exceptions derive from.
I think its pretty tricky and confusing:
What if your exception condition throws an exception as well? Where and how should that new exception be handled?
A try/catch around a catch block? meh..
Let other catch blocks handled that exception: StackOverflows yay :)
Since c# 7.0 this kind of stuff already supported. Here is full reference.
Here is code snippet.
try
{
SomeOperationThatThrowsException();
}
catch(TheFilteredException ex ) when (ex.ErrorCode==123)
{
DoSomethingWhenExceptionThrown();
}
I'm not sure I like it that much. First off, it sounded like a really neat idea, but then I came to think, that if add syntactic sugar for this kind of thing, people will likely abuse exceptions when a status code is more appropriate.
As a few people have already pointed out, this is already in VB, however you could easily do something similar in C#:
catch (Exception ex)
{
if (ex.Message.Contains("Yikes!"))
{
// Do your thing
}
...
else
{
throw;
}
}
So, it's really just syntactic sugar.
The thing about exceptions is that (as often discussed on this site) they violate the sequential structure of your program, by potentially skipping a lot of code and popping the stack when you really didn't want that. This is why I don't think they are good for anything but very exceptional conditions, and if you really can somehow handle these conditions, it should be somewhat of a pain (try{}catch{if(..)} etc.), so that people wont be likely to use exceptions for more than these exceptional conditions.

Categories

Resources