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.
Related
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.
What is the difference between:
catch
{
MessageBox.Show("Error.");
}
and:
catch (Exception ex)
{
MessageBox.Show("Error.");
//we never use ex, so is it better to use catch without arguments?
}
As of .NET 2, if you don't tweak the configuration? Nothing.
Before then, or with some config tweak I can't remember precisely, there was the possibility of an exception being thrown from unmanaged code which didn't get converted into an Exception-compatible object.
Note that there's another option in between, where you specify the type but no variable:
catch (Exception)
{
...
}
Personally I'd be very wary of catching an exception without even logging it. It may be required if you're calling a boneheaded API, but it's generally best avoided.
I think they are the same. But the second case raised a compiler warning because you declare an exception you didn't use. I rather like the first one because you say explicitly that you don't use the exception. There is also a third one
catch (Exception)
{
//do something
}
if you want to specify the type of exception but doesn't care about the exception itself.
Generally you should catch specific errors first.
But if you go for catching a general Exception like you do I'd say use the second case:
catch (Exception ex)
{
MessageBox.Show("Error.");
//we never use ex, so is it better to use catch without arguments?
}
this can help you with debbuging since the variable contains the stack trace, exception message...etc. Which you can use for logging the error or something that will help you preventing it.
Be very carefull using this approach, though:
MessageBox.Show("Error.");
Not keeping track of your errors somewhere(like a log file) can cause a really big mess.
In your second example you can reference exception data, like the stack trace, source, etc. It also gives a general message that is sometimes helpful. It tells you WHY you suffered an exception which is important when debugging.
Some exception can not be catch(Exception) catched.
Below excecption in mono on linux, should catch without parameter.
Otherwise runtime will ignore catch(Exception) statment.
System.Reflection.ReflectionTypeLoadException: The classes in the module cannot be loaded.
If you encounter the problem like that, try remove parameter of catch statement, log the context vars to find out error cause.
P.S. I don't know how on windows, the program run in windows is normal.
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
When we wrap a bunch of statements in a try/catch and one of these issues an exception, within the catch we have no way of knowing which of the statements caused the exception (the ex.stacktrace shows our current method (doit), its caller, its caller's caller, etc. but neither do1 or do2):
function doit() {
try {
do1();
do2();
[...]
}
catch (Exception ex) {
// what failed?
}
}
generally I've taken to wrapping all statements and rethrowing, sort of like:
private void do1() {
try {
// do whatever
} catch(Exception e) {
// write to my error log
throw new Exception("do1: " + e.Message, e.InnerException);
}
}
which leaves a trail of breadcrumbs in my log and makes the chain available for the upstream. The problem, of course, is that I have to wrap every method I write with this kind of code.
something tells me I'm being dumb about it. what is the right approach?
Ok, this is hard to get right because exception handling is a really really touchy subject and in the past people have fought religious wars over how to do this right.
First off: neither use an empty catch (try { ... } catch { ... }), nor catch(Exception ex).
The sole purpose of Exception-derived classes is to give you rich information about the kind of exception which occured so you can do something meaningful in your exception handler (if a thread crashed restart it, if a db connection failed non-permanently try again, then fail, etc).
People tend to use a catch-all handler for the outermost part of their code to log uncaught exceptions and this is kind of OK, but in any case you should either prompt the user or rethrow the exception (using throw, not throw ex - there is a ton of discussion about this as well).
Basically you do not programmatically care about where the Exception occured at all.
You can either handle it or you can't. If you can't handle it then you don't catch it.
Addendum: The most important reason for this "if you can do something about it, do so, otherwise dont you dare touch that exception" philosophy is that silently caught exceptions (whether logged or not) can lead to really hard-to-find bugs. Just pushing them out to a logfile might not be enough because in a live system you may not get the fully annotated stack trace (with line numbers and everything).
Addendum 2: Take for instance a textbox which expects an integer input. If the user supplies a string you cannot meaningfully process the input, maybe a conversion exception gets thrown, you catch that specific exception and reset the textbox to its old value and maybe inform the user about the erroneous input. Alternatively your program might either just die with an exception (bad design, you could recover from that exception) or silently go on showing the erroneous input, but still using the old value (bad design, the program is misleading).
If you are really sold on doing this (others have stated why this is bad already), use an Aspect Oriented Programming approach. This will make your life significantly easier and reduce the amount of code you end up writing and maintaining.
Take a look at PostSharp, it gives you a framework that allows you to decorate methods, classes, or namespaces with attributes that will generate this boilerplate error handling for you.
#Branko nailed it in the comments: the exception's stack trace shows the point where the exception was thrown, not where it was caught.
+1 for #ChaosPandion's comment: this is a very, very, very bad idea.
try and catch seem to me to be probably the single worst designed modern programming mechanism. We no longer have the ability to handle errors as we go; we must fail the entire procedure if a single exception occurs, unless we do something horrifying like try every statement individually. There is no longer the option of recovering, only failing as gracefully as possible.
The best pattern for this I have found so far is to wrap every user event in a try/catch (using a method, not an explicit try every time). Ex:
public static class Defines
{
public static bool TryAction(Action pAction)
{
try { pAction(); return true; }
catch(Exception exception) { PostException(exception); return false; }
}
}
...
private void DoSomething(int pValue)
{
...
}
private void MyControl_MyEvent(object pSender, MyEventArgs pEventArgs)
{
Defines.TryAction(() => DoSomething(pEventArgs.Data));
}
Beyond that, just try to write exception-less code. Only use explicit trys when you are very likely to get an exception and want to do a little more than just fail gracefully.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
Sometimes I do this and I've seen others doing it too:
VB:
Try
DontWannaCatchIt()
Catch
End Try
C#:
try
{
DontWannaCatchIt();
}
catch {}
I know I should catch every important exception that I'm expecting and do something about it, but sometimes it's not important to - or am I doing something wrong?
Is this usage of the try block incorrect, and the requirement of at least one catch or finally block an indication of it?
Update:
Now I understand the reason for this, and it's that I should at least comment on the empty catch block so others understand why it's empty. I should also catch only the exceptions I'm expecting.
Luckily for me I'm coding in VB so I can write it in just one catch:
Catch ex As Exception When TypeOf ex Is IOException _
OrElse TypeOf ex Is ArgumentException _
OrElse TypeOf ex Is NotSupportedException _
OrElse TypeOf ex Is SecurityException _
OrElse TypeOf ex Is UnauthorizedAccessException
'I don't actually care.
End Try
If you don't want to catch it, why are you using try in the first place?
A try statement means that you believe something can go wrong, and the catch says that you can adequately handle that which goes wrong.
So in your estimation:
try
{
//Something that can go wrong
}
catch
{
//An empty catch means I can handle whatever goes wrong. If a meteorite hits the
//datacenter, I can handle it.
}
That catch swallows any exceptions that happen. Are you that confident in your code that you can handle anything that goes wrong gracefully?
The best thing to do (for both yours and your maintenance programmer's sanity) is to explicitly state that which you can handle gracefully:
try
{
//Something that could throw MeteoriteHitDatacenterException
}
catch (MeteoriteHitDatacenterException ex)
{
//Please log when you're just catching something. Especially if the catch statement has side effects. Trust me.
ErrorLog.Log(ex, "Just logging so that I have something to check later on if this happens.")
}
No, you should not catch every important exception. It is okay to catch and ignore exceptions you don't care about, like an I/O error if there's nothing you can do to correct it and you don't want to bother reporting it to the user.
But you need to let exceptions like StackOverflowException and OutOfMemoryException propagate. Or, more commonly, NullReferenceException. These exceptions are typically errors that you did not anticipate, cannot recover from, should not recover from, and should not be suppressed.
If you want to ignore an exception then it is good to explicitly write an empty catch block in the code for that particular exception. This makes it clear exactly what exceptions you're ignoring. Ignoring exceptions very correctly is an opt-in procedure, not an opt-out one. Having an "ignore all exceptions" feature which can then be overridden to not ignore specific types would be a very bad language feature.
How do you know what types of exceptions are important and should not be caught? What if there are exceptions you don't know about? How do you know you won't end up suppressing important errors you're not familiar with?
try
{
}
// I don't care about exceptions.
catch
{
}
// Okay, well, except for system errors like out of memory or stack overflow.
// I need to let those propagate.
catch (SystemException exception)
{
// Unless this is an I/O exception, which I don't care about.
if (exception is IOException)
{
// Ignore.
}
else
{
throw;
}
}
// Or lock recursion exceptions, whatever those are... Probably shouldn't hide those.
catch (LockRecursionException exception)
{
throw;
}
// Or, uh, what else? What am I missing?
catch (???)
{
}
No catch or finally is invalid. Empty catch or finally is valid. Empty catch means you don't care about exceptions, you just try to do something and it doesn't matter if it doesn't work, you just want to go on. Useful in cleanup functions for example.
Also if you haven't to do something about an error maybe you should specify what kind of exception the program has to ignore.
If you have to ignore every exception, I can't see why you can't use try/catch in this way.
It's usually a mistake. Exceptions signal, well, exceptional behavior; when an exception is thrown it should mean that something went wrong. So to continue normal program flow as if nothing went wrong is a way of hiding an error, a form of denial. Instead, think about how your code should handle the exceptional case, and write code to make that happen. An error that propagates because you've covered it up is much harder to debug than one that surfaces immediately.
It's not made easy for you to do because it's considered bad practice by the majority of developers.
What if someone later adds a method call to the body of DontWannaCatchIt() that does throw an exception worth catching, but it gets swallowed by your empty catch block? What if there are some exceptions that you actually would want to catch, but didn't realize it at the time?
If you absolutely must do this, try to be as specific as possible with the type of exception you're going to catch. If not, perhaps logging the exception is an option.
An error exists, has been thrown, and needs to go somewhere. Normal code flow has been aborted and the fan needs cleaned.
No catch block = indeterminate state. Where should the code go? What should it do?
An empty catch block = error handled by ignoring it.
Note: VBA has a vile "On Error Continue"...
The reason I've heard is that if your try fails for ANY reason, giving you control of the error response is highly preferable to giving the Framework control of it, i.e., yellow screen or error 500.
what if you write only code with try
try
{
int j =0;
5/j;
}
this would equivalent to write
int j =0;
5/j;
so writing try does not make any sense , it only increse your count of lines.
now if you write try with empty catch or finally , you are explicitley instructing runtime to behave differently.
so that' why i think empty try block is not possible.
Yes, it is incorrect. It's like goto: one per 100 KLoc is fine, but if you need many of these, you are doing it wrong.
Swallowing exceptions without any reactions is one of the worse things in error handling, and it should at least be explicit:
try
{
DontWannaCatchIt();
}
catch
{
// This exception is ignored based on Spec Ref. 7.2.a,
// the user gets a failure report from the actual results,
// and diagnostic details are available in the event log (as for every exception)
}
The further-away-look:
Error handling is an aspect: in some contexts, an error needs to be thrown and propagate up the call stack (e.g. you copy a file, copy fails).
Calling the same code in a different context might require the error to be tracked, but the operation to continue (e.g. Copying 100 files, with a log indicating which files failed).
Even in this case, an empty catch handler is wrong.
With most languages, there is no other direct implementation than to try+catch within the loop, and build the log in the catch handler. (You could build a mroe flexible mechanism, though: Have a per-call-thread handler that can either throw, or stow away the message. However, interaction with debugging tools suffers without direct language support.)
A sensible use case would be implementing a TryX() from a X(), but that would have to return the exception in question.