Multiple try-catch or one? - exception

Normally, I'd do this:
try
{
code
code that might throw an anticipated exception you want to handle
code
code that might throw an anticipated exception you want to handle
code
}
catch
{
}
Are there any benefits to doing it this way?
code
try
{
code that might throw an anticipated exception you want to handle
}
catch
{
}
code
try
{
code that might throw an anticipated exception you want to handle
}
catch
{
}
code
Update:
I originally asked this question w/reference to C#, but as A. Levy commented, it could apply to any exception handling language, so I made the tags reflect that.

It depends. If you want to provide special handling for specific errors then use multiple catch blocks:
try
{
// code that throws an exception
// this line won't execute
}
catch (StackOverflowException ex)
{
// special handling for StackOverflowException
}
catch (Exception ex)
{
// all others
}
If, however, the intent is to handle an exception and continue executing, place the code in separate try-catch blocks:
try
{
// code that throws an exception
}
catch (Exception ex)
{
// handle
}
try
{
// this code will execute unless the previous catch block
// throws an exception (re-throw or new exception)
}
catch (Exception ex)
{
// handle
}

If I could choose the second I would probably separate this into two functions.

Neither, just use multiple catch blocks for specific exceptions (unless there is just a ton of code in the block and only a couple of lines may throw an exception.In that case I would go with the second method).

You're thinking about this the wrong way. What do you need to do in your catch blocks? If you would recover from any of the possible exceptions by running the same code, no matter which operation threw the exception, then use one catch block. If you need to do different clean-up operations depending on which operation threw, then use multiple catch blocks.
Also, if you can use try/finally or the RAII pattern instead of try/catch, then you should.

Second method is better in my opinion because it allows you to trap errors with more accuracy.
Also wrapping your entire code inside one big try/catch block is bad, if your app has some sort of problem and it crashes but since you trapped a big generic execption the chance that you can actualy handle it correctly is lower.
You should have spesfic parts inside try catch, like if your reading a file or taking user input. That way you can better handle that exeception

There are time we want to show specific error to user.
try{
try{
... send message
}
catch(exception e){
...log error
...rethrow send related error/show custom error
}
try{
...try to receive response
}
catch(exception e){
...show receive related error
}
//finally close the connection
}finally{
...close connection
}

I prefer the second method - it makes debugging easier, error handling more accurate and also feeds nicely into your unit testing nicely too.

I would go for the 2nd option, but whenever I see this code pattern my first feeling is to think about splitting it into multiple functions/methods. Obviously whether to do so depends on what the code is doing ;)

It depends on the nature of the type of errors happen in your code.
If the handling of those errors you are going to do is same go for single try ... catch for that group of code. Else it will be too tedious.
If the errors required different handling, separate it because you have to.
DO NOT APPLY A SINGLE METHOD FOR ALL CASES. PROGRAMMING MOST OF THE TIME IS CONTEXT SPECIFIC :)
You need to reach a balance of "GOOD/COMPLEX" and "BAD/SIMPLE". The more you code, you will be less stuck in this kind of dilemma :)
Happy programming!

Second method. Keeping the code that might throw an exception separate from other code - keeps the section smaller and easier to manage instead of wrapping all code, even that which will not throw exceptions.

2nd way but ideally use code guards - try/catch can be costly, if you catch an exception.

Related

Difference between throwing Exception and throwing a specific Exception such as NullPointerException

I am wondering what is the difference between throwing just Exception and throwing a specific Exception such as NullPointer Exception.
To my current knowledge an Exception should be able to catch any type of exception where as using a specific Exception expects that only that exception type can be thrown.
Example:
void test(String testString) throws Exception;
vs
void test(String testString) throws NullPointerException;
If this is correct than to me it makes sense to just always throw Exception and to never name a specific exception. Am I missing something important here? Does it at the very least effect performance at all? A lot of people are looking between throwing and catching exceptions but nobody asks this very basic question.
I do not see a benefit of throwing any exception except Exception.
To start off, Exception is a base type of every Exception. Just like object is for everything.
By throwing a specific Exception you provide more information to the consumer of what has happened.
Imagine scenario where you get a plain Exception without a message, consumer is lost. When for example framework throws a NullReferenceException, then you are aware of a fact that one of your objects does not have a reference which it was trying to access.
This is how you can chain exceptions and make use of their types:
try
{
throw new NotImplementedException();
}
catch(NullReferenceException ex)
{
// Logic for NullReference exception if needed.
}
catch(NotImplementedException ex)
{
// This will be executed.
}
catch(Exception ex)
{
// Will catch every exception.
}
There are at least two reasons why you would want to throw a specific kind of exception:
If a program fails with an exception, you will have more information with which to determine what went wrong. Compare seeing Exception with FileNotFoundException. The latter clearly gives you more information.
In some cases, the code will want to catch certain kinds of exceptions. For example, when working with serial ports, you might want to catch and handle a TimeoutException differently from a NullReferenceException.
The NullPointerException you mentioned is a very good example from the regular Exception because it is a subclass of RuntimeException. Any throwing of (a subclass of) RuntimeException does not have to be caught or declared.
Any other (=not a subclass of RuntimeException) Exception has to be handled in your code by either a try/catch block or a throws declaration. Otherwise, your code will not even compile! That forces you as a developer to handle errors that might pop up.
As for why using different Exception types is useful, consider the following simple example that uses multiple catch statements:
void doDBStuff(){
try {
performStatement(someStatement);
} catch(SQLException e){
//invalid SQL syntax, something is broken
} catch(AuthenticationException e){
//invalid user credentials for the db, inform the user to change these values
}
In this example, two different exceptions end up in two different catch blocks which lets you handle these errors differently.
It's a best practice to throw specific exceptions, instead of a generic one. This is because the caller might want to treat the exceptions differently, for example in a WebApi you might want to return a Bad Request response (400) for a ArgumentNullException, but you might want to return a different result for other types of exceptions. For example you might actually throw a custom NotFoundException and then the controller would catch it and return a Not Found response (404) instead.
Basically if you throw specific exceptions you are allowing the consumer code to handle the different exception scenarios the way they want.

Why Exception inside a method should be handled within the method itself and not outside?

Consider a method() that throws some exception in its body.
Consider the following scenarios:
Scenario 1:
{
//..
// ..
method(); //Exception handled inside the method
//..
//..
}
In this case the exception should be handled within the method() itself.
Also consider this:
Scenario 2:
{
//..
//..
try{
method(); //Exception not handled with-in the method
}
catch(){}
//..
// ..
}
Why a situation like scenario 2 is not allowed? ie why it is forced that the exception should be handled within the method?
You can add throws clause to your method and make it throw an exception, which can be handled, as mentioned in Situation 2. So its allowed, like this:-
void method() throws Exception{
}
Both scenarios are allowed. The restriction (if that's the right term) that Java imposes is that the exception must be handled somewhere.
In the first scenario, the called method handles the exception itself - so there's no need for the try-catch in the calling method.
The second scenario is valid - but only if method() includes the throws declaration to indicate that the exception must be handled somewhere else.
void method() throws Exception
{
}
It is allowed!
use as follows
public void method() throws ClassNotFoundException {
to catch a ClassNotFoundException.
(In most cases you should not throw a bare Exception, like other posters simplified)
Whether to chatch inside or outside is software design. There is no rule of thumb.
My experience is that catching outside leads to less complex code, which can be better unit tested .
Look for design pattern "last line of defense":
That means that in your top most class e.g in main() there is a catch (Exception ex) {
which catches when no other method catched it. in that case you can log the exception and (try to) safely shut down your system. This is the last line of defense.
Note: spmetimes it also makes sense to catch(Throweable th),
If you handle exception using senario-2, then cannot map the exception to the actual one. i.e you cannot state it as per the code in block. So please handle the exception to the spot itself, so that you can specifically explain why the exception has occurred.
As said above, the idea is to throw early and catch late. Overall, you want to minimize exceptions you throw by simply making your logic "flow". But there are always situations which are tricky to handle, or obfuscate code too much, so it is worth ensuring the user understands the risks of using certain methods and handles them accordingly.
TL;DR: Never trap InterruptedException unless you really mean to. It almost always needs to be thrown.
This great question is actually a very important design decision. Getting this right is difficult and getting this right across an entire team is even more difficult. The answer to the question lies within your implementation. Does the error need to be immediately shown to the user? Do you have an auxiliary method to recover from the failure? Is the exception a fatal event?
Please do yourself a favor and never write an empty exception handler. You will be very happy to have put in a log.debug statement in there when things go awry. Other than that: learn what every exception means and respond to it in the most graceful way possible.

What is the usefulness of using throw? and in catch?

From what I understand throw causes an exception.
It looks like it can be used to test your catch exception.
What are the benefits/uses for it? Why would you want to purposely cause an exception?
Why use throw in catch? Seems like it catches the exception just to cause an exception again.
try
{
//blah
}
catch
{
throw;
}
throw; rethrows the current exception. It's used for when you want to catch an exception and do some handling of your own, but otherwise still want the exception to propagate more-or-less as if you never caught it.
The difference (in languages that let you just say throw;, like C#) is that when you rethrow an exception, the original stack trace remains mostly intact. (It includes the line where you rethrew the exception rather than the line where the exception occurred in the corresponding try block, but otherwise the whole stack trace is preserved.) If you say throw the_exception_you_caught;, it's usually treated as if you threw a brand new exception from right there -- the existing stack trace gets obliterated and a new one starts from that point.
Exceptions are mechanism for error handling. For instance, you may throw an exception to indicate that a webservice call has timed out, or bad input as been provided to a method. The idea is that calling code knows how to deal with these exceptions and handles them gracefully — perhaps fixing what's wrong in the case of bad input (by prompting the user) or by trying a callout a second time.
A catch block is where you do your handling of the error, and in certain scenarios you may want to do some local cleanup in the method running, but then you still need to report the error to calling methods, so you throw the exception once more (or throw a different, maybe more generic or specific exception) which you then handle in your calling code.
Description
You can do this to, for example, log something and give the exception back to the calling method / assembly.
You can handle the exception and signals the caller that a exception is happend instead of return a boolean that indicates if the method has success.
This is useful for unit tests and more.
Sample
try
{
//blah
}
catch
{
// log exception to textfile of database
throw;
}
This is a common pattern in .Net code. It's used when the caller wants to either log, wrap or react to an exception and then pass it back up to the caller. For example
try {
SomeFunction();
} catch {
CloseMyResource();
throw;
}
The advantage of throw vs throw exceptionVariable is that throw preserves the original stack trace. The next person to catch the exception sees the original stack trace. This is essentially for tracking down errors in deep call stacks.
I think it may be better to think of a throw as your informed reaction to an exception in your code rather than the cause. Semantics I know but it helps.
You throw a different exception in a catch to add information. Your converting what may be a generic OS exception into one meaningful to your application. e.g. Out of memory exception may be caught and a new exception with the out of memory as the inner exception be throw saying something like "Error while computing the answer to life the universe and everything". More useful that just an out of memory exception.
You may use a 'throw' on its own as a rethrow. The catch allows you to do something before rethrowing. If we are talking C# check out 'finally'.
When something really bad happens, that ought not happen, then you can abort and inform the caller by throwing an exception. It means that you do not need to have every method returning result codes and every caller testing fault/success codes. It also nicely abstracts who handles such 'exceptions' or even if you just leave it to the OS.
Quick answer ... it makes your code simpler and gives you better control of aborting and handling exceptions. Think of it as a messaging/abort system.
You would re-throw the same exception if you wanted to do some logging here or some clean up but would like to still have the calling functions further up the call stack to have to handle that same exception.
A more typical use would be:
try {
// ...
} catch (EmailException ex) {
SMS.AlertError("Email is not working", ex);
throw;
}
If you throw ex you will have stripped out information such as the call stack from the exception.
The some function above that would:
try {
// ...
} catch (Exception ex) {
WorkFlowProblems.Add(new OrderNotSentException("Email did not work", ex));
View.ShowError("Could not send order!");
}
Here you make a new exception and set it's "inner exception" to be original cause. This is a good way for multi-part systems to have the right level of information about what went wrong and at what level.
Doing this preserves the stack trace. In your example, it's not useful, however, you could catch the exception, log it and then rethrow so that the exception bubbles up to be handled by code higher up.
The place where throwing exception (in my opinion) is MOST useful is when you want to create an instance of a new object and there's some possibility that the instance needs to fail in creation, in which case the instance can be made to remain null (since constructors don't "return" anything... so for example...
Foo foo = new Foo();//
//at this line foo may or may not be the exact thing you want it to be, depending on whatever conditions made the creation of Foo possible.
So, Foo throws an exception you can do this:
Foo foo = null;
try{
foo = new Foo();
}catch(FooException fe){
//here you can find out if Foo didn't get instantiated as you wanted it to
}
//and here you can test if foo is still null.

Why are empty catch blocks a bad idea? [closed]

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 7 years ago.
Improve this question
I've just seen a question on try-catch, which people (including Jon Skeet) say empty catch blocks are a really bad idea? Why this? Is there no situation where an empty catch is not a wrong design decision?
I mean, for instance, sometimes you want to get some additional info from somewhere (webservice, database) and you really don't care if you'll get this info or not. So you try to get it, and if anything happens, that's ok, I'll just add a "catch (Exception ignored) {}" and that's all
Usually empty try-catch is a bad idea because you are silently swallowing an error condition and then continuing execution. Occasionally this may be the right thing to do, but often it's a sign that a developer saw an exception, didn't know what to do about it, and so used an empty catch to silence the problem.
It's the programming equivalent of putting black tape over an engine warning light.
I believe that how you deal with exceptions depends on what layer of the software you are working in: Exceptions in the Rainforest.
They're a bad idea in general because it's a truly rare condition where a failure (exceptional condition, more generically) is properly met with NO response whatsoever. On top of that, empty catch blocks are a common tool used by people who use the exception engine for error checking that they should be doing preemptively.
To say that it's always bad is untrue...that's true of very little. There can be circumstances where either you don't care that there was an error or that the presence of the error somehow indicates that you can't do anything about it anyway (for example, when writing a previous error to a text log file and you get an IOException, meaning that you couldn't write out the new error anyway).
I wouldn't stretch things as far as to say that who uses empty catch blocks is a bad programmer and doesn't know what he is doing...
I use empty catch blocks if necessary. Sometimes programmer of library I'm consuming doesn't know what he is doing and throws exceptions even in situations when nobody needs it.
For example, consider some http server library, I couldn't care less if server throws exception because client has disconnected and index.html couldn't be sent.
Exceptions should only be thrown if there is truly an exception - something happening beyond the norm. An empty catch block basically says "something bad is happening, but I just don't care". This is a bad idea.
If you don't want to handle the exception, let it propagate upwards until it reaches some code that can handle it. If nothing can handle the exception, it should take the application down.
I think it's okay if you catch a particular exception type of which you know it's only going to be raised for one particular reason, and you expect that exception and really don't need to do anything about it.
But even in that case, a debug message might be in order.
There are rare instances where it can be justified. In Python you often see this kind of construction:
try:
result = foo()
except ValueError:
result = None
So it might be OK (depending on your application) to do:
result = bar()
if result == None:
try:
result = foo()
except ValueError:
pass # Python pass is equivalent to { } in curly-brace languages
# Now result == None if bar() returned None *and* foo() failed
In a recent .NET project, I had to write code to enumerate plugin DLLs to find classes that implement a certain interface. The relevant bit of code (in VB.NET, sorry) is:
For Each dllFile As String In dllFiles
Try
' Try to load the DLL as a .NET Assembly
Dim dll As Assembly = Assembly.LoadFile(dllFile)
' Loop through the classes in the DLL
For Each cls As Type In dll.GetExportedTypes()
' Does this class implement the interface?
If interfaceType.IsAssignableFrom(cls) Then
' ... more code here ...
End If
Next
Catch ex As Exception
' Unable to load the Assembly or enumerate types -- just ignore
End Try
Next
Although even in this case, I'd admit that logging the failure somewhere would probably be an improvement.
Per Josh Bloch - Item 65: Don't ignore Exceptions of Effective Java:
An empty catch block defeats the purpose of exceptions
At the very least, the catch block should contain a comment explaining why it is appropriate to ignore the exception.
Empty catch blocks are usually put in because the coder doesn't really know what they are doing. At my organization, an empty catch block must include a comment as to why doing nothing with the exception is a good idea.
On a related note, most people don't know that a try{} block can be followed with either a catch{} or a finally{}, only one is required.
An empty catch block is essentially saying "I don't want to know what errors are thrown, I'm just going to ignore them."
It's similar to VB6's On Error Resume Next, except that anything in the try block after the exception is thrown will be skipped.
Which doesn't help when something then breaks.
This goes hand-in-hand with, "Don't use exceptions to control program flow.", and, "Only use exceptions for exceptional circumstances." If these are done, then exceptions should only be occurring when there's a problem. And if there's a problem, you don't want to fail silently. In the rare anomalies where it's not necessary to handle the problem you should at least log the exception, just in case the anomaly becomes no longer an anomaly. The only thing worse than failing is failing silently.
Empty catch blocks are an indication of a programmer not knowing what to do with an exception. They are suppressing the exception from possibly bubbling up and being handled correctly by another try block. Always try and do something with the exception you are catching.
I think a completely empty catch block is a bad idea because there is no way to infer that ignoring the exception was the intended behavior of the code. It is not necessarily bad to swallow an exception and return false or null or some other value in some cases. The .net framework has many "try" methods that behave this way. As a rule of thumb if you swallow an exception, add a comment and a log statement if the application supports logging.
If you dont know what to do in catch block, you can just log this exception, but dont leave it blank.
try
{
string a = "125";
int b = int.Parse(a);
}
catch (Exception ex)
{
Log.LogError(ex);
}
Because if an exception is thrown you won't ever see it - failing silently is the worst possible option - you'll get erroneous behavior and no idea to look where it's happening. At least put a log message there! Even if it's something that 'can never happen'!
I find the most annoying with empty catch statements is when some other programmer did it. What I mean is when you need to debug code from somebody else any empty catch statements makes such an undertaking more difficult then it need to be. IMHO catch statements should always show some kind of error message - even if the error is not handled it should at least detect it (alt. on only in debug mode)
It's probably never the right thing because you're silently passing every possible exception. If there's a specific exception you're expecting, then you should test for it, rethrow if it's not your exception.
try
{
// Do some processing.
}
catch (FileNotFound fnf)
{
HandleFileNotFound(fnf);
}
catch (Exception e)
{
if (!IsGenericButExpected(e))
throw;
}
public bool IsGenericButExpected(Exception exception)
{
var expected = false;
if (exception.Message == "some expected message")
{
// Handle gracefully ... ie. log or something.
expected = true;
}
return expected;
}
Generally, you should only catch the exceptions you can actually handle. That means be as specific as possible when catching exceptions. Catching all exceptions is rarely a good idea and ignoring all exceptions is almost always a very bad idea.
I can only think of a few instances where an empty catch block has some meaningful purpose. If whatever specific exception, you are catching is "handled" by just reattempting the action there would be no need to do anything in the catch block. However, it would still be a good idea to log the fact that the exception occurred.
Another example: CLR 2.0 changed the way unhandled exceptions on the finalizer thread are treated. Prior to 2.0 the process was allowed to survive this scenario. In the current CLR the process is terminated in case of an unhandled exception on the finalizer thread.
Keep in mind that you should only implement a finalizer if you really need one and even then you should do a little as possible in the finalizer. But if whatever work your finalizer must do could throw an exception, you need to pick between the lesser of two evils. Do you want to shut down the application due to the unhandled exception? Or do you want to proceed in a more or less undefined state? At least in theory the latter may be the lesser of two evils in some cases. In those case the empty catch block would prevent the process from being terminated.
I mean, for instance, sometimes you want to get some additional info from somewhere (webservice, database) and you really don't care if you'll get this info or not. So you try to get it, and if anything happens, that's ok, I'll just add a "catch (Exception ignored) {}" and that's all
So, going with your example, it's a bad idea in that case because you're catching and ignoring all exceptions. If you were catching only EInfoFromIrrelevantSourceNotAvailable and ignoring it, that would be fine, but you're not. You're also ignoring ENetworkIsDown, which may or may not be important. You're ignoring ENetworkCardHasMelted and EFPUHasDecidedThatOnePlusOneIsSeventeen, which are almost certainly important.
An empty catch block is not an issue if it's set up to only catch (and ignore) exceptions of certain types which you know to be unimportant. The situations in which it's a good idea to suppress and silently ignore all exceptions, without stopping to examine them first to see whether they're expected/normal/irrelevant or not, are exceedingly rare.
There are situations where you might use them, but they should be very infrequent. Situations where I might use one include:
exception logging; depending on context you might want an unhandled exception or message posted instead.
looping technical situations, like rendering or sound processing or a listbox callback, where the behaviour itself will demonstrate the problem, throwing an exception will just get in the way, and logging the exception will probably just result in 1000's of "failed to XXX" messages.
programs that cannot fail, although they should still at least be logging something.
for most winforms applications, I have found that it suffices to have a single try statement for every user input. I use the following methods: (AlertBox is just a quick MessageBox.Show wrapper)
public static bool TryAction(Action pAction)
{
try { pAction(); return true; }
catch (Exception exception)
{
LogException(exception);
return false;
}
}
public static bool TryActionQuietly(Action pAction)
{
try { pAction(); return true; }
catch(Exception exception)
{
LogExceptionQuietly(exception);
return false;
}
}
public static void LogException(Exception pException)
{
try
{
AlertBox(pException, true);
LogExceptionQuietly(pException);
}
catch { }
}
public static void LogExceptionQuietly(Exception pException)
{
try { Debug.WriteLine("Exception: {0}", pException.Message); } catch { }
}
Then every event handler can do something like:
private void mCloseToolStripMenuItem_Click(object pSender, EventArgs pEventArgs)
{
EditorDefines.TryAction(Dispose);
}
or
private void MainForm_Paint(object pSender, PaintEventArgs pEventArgs)
{
EditorDefines.TryActionQuietly(() => Render(pEventArgs));
}
Theoretically, you could have TryActionSilently, which might be better for rendering calls so that an exception doesn't generate an endless amount of messages.
You should never have an empty catch block. It is like hiding a mistake you know about. At the very least you should write out an exception to a log file to review later if you are pressed for time.

How to deal with exceptions

My technical lead insists on this exception mechanism:
try
{
DoSth();
}
catch (OurException)
{
throw;
}
catch (Exception ex)
{
Util.Log(ex.Message, "1242"); // 1242 is unique to this catch block
throw new OurException(ex);
}
1242 here is an identifier of the catch method which we handle an exception other than OurException. Every catch block in the project must have a unique identifier so we can know where the exception occurred by looking at the logs.
For every method, we have to catch OurException and throw it. If an other type of exception is thrown, we have to log it and mask it by OurException before rethrowing it.
Is this a reasonable approach? If there are any, what are the better alternatives?
Edit: I've been told the stack trace does not produce meaningful results in release mode.
Are you suggesting catching and throwing generic exceptions is OK?
Edit2: Thank you all. I used your answers as part of my argument against this but I've been told you are not experienced enough and do not know how to deal with real life situations. I have to go this way.
You can also look into the Exception Handling Application block.
I have used it in a few projects and it is very useful. Especially if you want to later change how your exception handling works, and what information to capture.
I would think that using the stack trace would be much more intuitive than any identifier.
As far as the custom exception, why not do this?
try
{
DoSth();
}
catch(Exception ex)
{
Util.Log(ex.Message, ex.StackTrace);
if(ex is OurException) throw ex;
else throw new OurException(ex); // use the original exception as the InnerException
}
Also, I'm not sure why you'd want to rethrow an exception after it's been handled - can you explain the reasoning behind that?
#Ali A - A very valid point, so allow me to rephrase - why rethrow the exception instead of finishing the handling of it right here?
EDIT:
Instead of rethrowing, why not do this?
try
{
DoSth();
}
catch(Exception ex)
{
Util.HandleException(ex);
}
Util.HandleException:
public static void HandleException(ex)
{
Util.Log(ex); // Util.Log should log the message and stack trace of the passed exception as well as any InnerExceptions - remember, than can be several nested InnerExceptions.
// Any additional handling logic, such as exiting the application, or showing the user an error message (or redirecting in a web app)
}
That way, you know every exception only gets logged once, and you're not throwing them back into the wild to wreak any additional havoc.
Having the OurException is kinda weird. Usually, you want to have specialized catch blocks and then the last one, the one that catches a generic Exception is where you do your logging:
try
{
DoSomething();
}
catch (DivideByZeroException)
{
// handle it here, maybe rethrow it, whatever
}
// more catch blocks
catch (Exception)
{
// oops, this is unexpected, so lets log it
}
But what your doing will work. I do believe the 1242 should go though. Here's a method to print the method, filename, and line number you could use instead. I haven't tried it myself but it looks good:
[Conditional("DEBUG")]
public static void DebugPrintTrace()
{
StackTrace st = new StackTrace(true);
StackFrame sf = st.GetFrame(1); // this gets the caller's frame, not this one
Console.WriteLine("Trace "
+ sf.GetMethod().Name + " "
+ sf.GetFileName() + ":"
+ sf.GetFileLineNumber() + "\n");
}
I have two types of exceptions: repairable exception and fatal exception. If some object throw repairable exception, this is mean that error occur but object is not damaged and can be used over again. If some object throw fatal exception, this is means that object state is damaged, and any attempt to use object will lead with new error.
Update: all exceptions might be handled as soon as possible, and as close to error source as possible. For example, if object, stored in collection throws the fatal exception, exception handler just remove this object from collection and delete it, not all entire collection of objects.
From what I understand, the purpose of exceptions are to propagate unexpected errors. If you catch it close enough to the method that throws it, you are more in the context of how to handle it.
Your example is to catch an unexpected error, and rethrow that up the chain. This is not handling the exception, but wrapping it into your own.
But your wrapping does not seem to add any more value to the exception, but might even clutter things.
An extreme example:
void a() {
try {
c();
} catch(MyException1 ex) {
throw;
} catch(Exception ex) {
log(ex);
throw new MyException1(ex);
}
}
void b() {
try {
a();
} catch(MyException2 ex) {
throw;
} catch(Exception ex) {
log(ex);
throw new MyException2(ex);
}
}
Notice how that, in the earlier example, the original exception is logged twice. And it is wrapped in two exceptions.
When you log the same exception a few times it becomes harder to trace (since the log file grows rather big).
Of course this might be an extreme example, but I find it hard to believe that your entire application has only one type of exception in use. It does not describe sufficient all the different types of errors that might happen.
I personally prefer to log the exception only at the catch block where I handle it. Anywhere else might just create duplicated logging.
I think that having a hard coded number on the throw line is not a good practice, how do you know whether that number is being used or not?, or, which is the next error number to throw? Maybe you can have, at least, listed on an enum... not sure.
Everything looks right except for that weird number.
The stack trace will contain the information you need.
Seems to me that the stacktrace is a better way to handle this. What happens if you mistakenly reuse a number?
As far as whether this is a good idea or not, in the absence of any more information, I'd tend to say no. If every method invocation is wrapped in a try/catch block it will be very expensive. Generally, exceptions fall in to two camps -- those you can reasonably expect and deal with and those that are really bugs (or at least not successfully anticipated). Using a shotgun approach to catching all exceptions seems to me like it just might do more to hide the latter than help get them resolved. This would be especially true if at the top level you caught all exceptions so that the only record you have is the log message.
I fail to see how this is helpful. You can already know where the exception came from with the stack trace, and you are adding an unnecessary level of complication.
The drawbacks:
That number doesn´t inspire much confidence, stack trace is much better
Why have 2 catch blocks if your custom exception can be handled on the "catch(Exception ex)
"?
I think this is a bad pattern, because you have the information about the whole call stack readily available in the exception, there is no need to pseudo-handle the exception by logging and rethrowing it. Only catch an exception at a place where you really can do something about the problem.
Logging the stacktrace would be a lot better than the hardcoded number. The number tells you nothing about what routine called this one.
Also the number is a pain to manage, and error-prone at that.
edit: it is true that the stacktrace doesn't always produce meaningful results in release mode, but I think the same can be said of this hardcoded number scheme! :-)
With the language you're using, does the compiler provide macros with the current filename and line number? That would be better than trying to roll a unique number yourself. And, if you can't do that automatically, do it manually, or come up with some scheme to guarantee uniqueness that doesn't require some central allocation of numbers!
My application is built in release mode, and i use the Exception Handling Application Block, so i never have any catch ex blocks of code, it is caught by the EHAB, this itself writes to a log file with all the info i need; stack trace etc, time, etc.
the only problem with this is if someone has put
catch ex
{
//do stuff
throw ex;
}
as this will wipe out the stack trace.