This question already has answers here:
Why catch and rethrow an exception in C#?
(17 answers)
Closed 6 years ago.
I have some code which catches the exception, rolls back the transaction and then rethrow the exception.
catch ( Exception exSys ) {
bqBusinessQuery.RollBackTransaction();
throw exSys ;
}
If I use this code, VS Code analysis throws warning saying
Use 'throw' without an argument instead, in order to preserve the stack location where the exception was initially raised.
If I use the code
catch ( Exception exSys ) {
bqBusinessQuery.RollBackTransaction();
throw;
}
then I get a warning saying
The variable 'exSys' is declared but never used
How should I solve this problem?
Edit
I tried this method, but it doesn't work. system.exception class requires an extra message, along with inner exception. If I do that, it will throw a new message overriding the message from the original exception. I don't want to get the new exception, I want to throw the same exception with same message.
catch (System.Exception ex)
{
throw new System.Exception(ex);
}
Edit
catch (System.Exception ex)
{
throw new System.Exception("Test",ex);
}
Tried this method. And then manually caused an exception using throw new Exception("From inside");. Now, ex.Message returns "Test" instead of "From inside". I want to keep that "From inside" message as is. This suggested change will cause problem with error display code everywhere. :/
You do not have to bind a variable to the exception:
try
{
...
}
catch (Exception)
{
bqBusinessQuery.RollBackTransaction();
throw;
}
Actually, in your case, as you catch any exception, you do not have to even name the exception type:
try
{
...
}
catch
{
bqBusinessQuery.RollBackTransaction();
throw;
}
Or (as suggested #Zohar Peled) throw a new exception, using the caught exception as an inner exception. This way you both preserve the stack and give the exception more context.
try
{
...
}
catch (Exception e)
{
throw new Exception("Transaction failed", e);
}
If you actually want to use the exception for some processing (e.g. log it), but want to rethrow it intact, declare the variable, but use a plain throw:
try
{
...
}
catch (Exception e)
{
Console.WriteLine(e.Message);
throw;
}
catch (Exception)
{
bqBusinessQuery.RollBackTransaction();
throw;
}
If you don't plan on using the exception (e.g. passing the message somewhere) then you don't need to pull it out into a variable. You can simply catch, do custom thing and throw.
Related
Here is the code that I wrote to understand how exception handling works:
using System;
using System.IO;
class ExceptionHandling
{
public static void Main()
{
try
{
StreamReader streamReader = new StreamReader("C:\\Sample Files\\Data.txt");
Console.WriteLine(streamReader.ReadToEnd());
streamReader.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}
}
}
I understand the try block, but I am having a hard time to understand how catch block works. I know that Exception is a class and ex.Message is the exceptions message.
My questions is what is ex? If this is an object, then how can we use without instantiation? And what does putting Exception ex into parameter of catch do?
And finally are try and catch methods? If they yes, are they in System namespace?
ex is a variable of type Exception.
When code elsewhere fails, it will do something like throw new Exception("some message here");.
The throw keyword causes the exception (created by new) to be passed up the stack, and if it hits your catch, that code will execute with ex pointing to that exception object.
throw, try, and catch are not functions, they are keywords. They're language features like foreach and if.
ex is a variable referring to an exception object that is instantiated by either the object that raised the exception, one of its dependencies, or the .NET runtime.
You can create your own exceptions like any object, and then throw them:
var myException = new MyCustomException(/*...*/);
throw myException;
try-catch is a statement that is part of the syntax of the C# language.
The catch part does not need to reference the exception variable if you do not need to access any of its members in your handling code. The following is valid syntax:
try {
// some code that might throw IO exception
catch (IOException) {
Console.WriteLine("Exception thrown.");
}
Bonus tips:
It is generally bad practice to catch the base class Exception - you should typically catch the most specific derived exception that you are trying to handle in your catch clause.
When you are using a class that implements IDisposable like StreamReader, you should consider using the using statement.
If the code crashes anywhere the it will have because someone has instantiated and thrown (C# throw keyword) an instance of an Exception (most likely a subtype such as InvalidOperationException).
If this exception is raised inside the try, the catch will attempt to handle it by checking if it can be derived from Exception (which all .Net Exceptions do).
If you define a variable to hold the instance of the exception on your catch block the runtime will assign the exception to it.
So ex will be set by the runtime to the exception that occurred. Have a look using the Debugger to see more information about it.
You can handle just specific exceptions like so:
catch (NullReferenceException nre) { HandleNRE(nre); } //nre will be a NullReferenceException
catch (InvalidOperationException ioe) { HandleIOE(ioe); } //ioe will be an InvalidOperationException
catch (Exception e) { HandleEverythingElse(e); } //e will be whatever was thrown.
You can also have catch blocks without an ex, e.g.
catch (NullReferenceException) { /* Do nothing, who cares about nulls. */ }
I have the following code:
try
{
retval = axNTLXRemote.IsUnitPresent(_servers[0].IPAddress, 1, _servers[0].RemotePort, _servers[0].CommFailDelay * 1000);
}
catch (COMException ce)
{
throw ce;
}
Which gives me the followig warning which I want to get rid of:
CA2200 : Microsoft.Usage : 'Connect()' rethrows a caught exception and specifies it explicitly as an argument. Use 'throw' without an argument instead, in order to preserve the stack location where the exception was initially raised.
I have read the following The difference between try/catch/throw and try/catch(e)/throw e and I understand that the 'throw ce; will reset the stack trace and make it appear as if the exception was thrown from that function.
I want to simply change it to a 'throw' instead of a 'throw ce' which will get rid of the warning.
What is the difference in the following catches:
catch (COMException ce)
{
throw;
}
and
catch (COMException)
{
throw;
}
Do I only need to have 'COMException ce' if I wish to somehow use the ce variable?
Also, when I perform a 'throw' or 'throw ce', is it the calling function that will handle or catch it?? I'm a little unclear about this.
The only difference is that with catch (COMException ce), you are assigning the exception to a variable, thereby letting you access it within the catch block. Other than that, it is in every way identical.
I'm not sure what the question is here. If you want to access the exception object, you must give it a variable name in the catch clause.
No matter how or where an exception is thrown, the exception will bubble up through the call stack to the closest catch block that matches.
Here's an example.
void Method1()
{
try
{
Method2();
}
catch // this will catch *any* exception
{
}
}
void Method2()
{
try
{
Method3();
}
catch (COMException ex) // this will catch only COMExceptions and exceptions that derive from COMException
{
}
}
void Method3()
{
// if this code were here, it would be caught in Method2
throw new COMException();
// if this code were here, it would be caught in Method1
throw new ApplicationException();
}
I'm sure someone will jump in with an uber-technical answer, but in my experience the answer to your first two questions is that there is no difference, and as you stated you'd only include ce if you intended to use it to write the stack trace to a log or display the message to the user or similar.
The throw will send the exception up the chain. That may be the calling method or, if your method has several nested try/catch blocks, it will send the exception to the next try/catch block that the current try/catch block is nested within.
Here are a couple good resources to check out if you want to read further on the subject:
Exception Handling
Design Guidelines for Exceptions
There is no difference in both cases, but only when exception variable should be used for stack/message etc.
So:
catch(ComException);
and
catch(ComException ex);
statements will produce similar MSIL, except local variable for ComException object:
.locals init ([0] class [mscorlib]System.Exception ex)
Up to now, whenever I wanted to show an exception thrown from my code I used:
try
{
// Code that may throw different exceptions
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
I used the above code mainly for debugging reasons, in order to see the exact type of exception and the according reason the exception was thrown.
In a project I am creating now, I use several try-catch clauses and I would like to display a popup message in case of an exception, to make it more "user friendly". By "user friendly", I mean a message that would hide phrases like Null Reference Exception or Argument Out Of Range Exception that are currently displayed with the above code.
However I still want to see relevant info with the type of exception that created the message.
Is there a way to format the displayed output of thrown exceptions according to previous needs?
You can use .Message, however I wouldn't recommend just catching Exception directly. Try catching multiple exceptions or explicitly state the exception and tailor the error message to the Exception type.
try
{
// Operations
}
catch (ArgumentOutOfRangeException ex)
{
MessageBox.Show("The argument is out of range, please specify a valid argument");
}
Catching Exception is rather generic and can be deemed bad practice, as it maybe hiding bugs in your application.
You can also check the exception type and handle it accordingly by checking the Exception type:
try
{
}
catch (Exception e)
{
if (e is ArgumentOutOfRangeException)
{
MessageBox.Show("Argument is out of range");
}
else if (e is FormatException)
{
MessageBox.Show("Format Exception");
}
else
{
throw;
}
}
Which would show a message box to the user if the Exception is an ArgumentOutOfRange or FormatException, otherwise it will rethrow the Exception (And keep the original stack trace).
try
{
/////Code that may throws several types of Exceptions
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
Use above code.
Can also show custom error message as:
try
{
/////Code that may throws several types of Exceptions
}
catch (Exception ex)
{
MessageBox.Show("Custom Error Text "+ex.Message);
}
Additional :
For difference between ex.toString() and ex.Message follow:
Exception.Message vs Exception.ToString()
All The details with example:
http://www.dotnetperls.com/exception
Exception.Message provides a more (but not entirely) user-friendly message than Exception.ToString(). Consider this contrived example:
try
{
throw new InvalidOperationException();
}
catch(InvalidOperationException ex)
{
Console.WriteLine(ex.ToString());
}
Although Message yields a simpler message than ToString() the message displayed will still not mean much to the user. It won't take you much effort at all to manually swallow exceptions and display a custom message to the user that will assist them in remedying this issue.
try
{
using (StreamReader reader = new StreamReader("fff")){}
}
catch(ArgumentException argumentEx)
{
Console.WriteLine("The path that you specified was invalid");
Debug.Print(argumentEx.Message);
}
catch (FileNotFoundException fileNotFoundEx)
{
Console.WriteLine("The program could not find the specified path");
Debug.Print(fileNotFoundEx.Message);
}
You can even use Debug.Print to output text to the immediate window or output window (depending on your VS preferences) for debugging purposes.
You can use Exception.Message property to get a message that describes the current exception.
catch (Exception ex)
{
MessageBox.Show(ex.Messagge());
}
try this code :
try
{
// Code that may throw different exceptions
}
catch (Exception exp)
{
MessageBox.Show(exp.Message());
}
The trick is using the Message method of the exception:
catch (Exception ex)
{
MessageBox.Show(this, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
Let us say we have an external server which we use (e.g.-telephony station, etc.). Also we have the next code:
try
{
externalService.CreateCall(callParams);
}
catch (Exception ex)
{
_log.Error("Unexpected exception when trying execute an external code.", ex);
_callService.UpdateCallState(call, CallState.Disconnected, CallOutcome.Failed);
throw;
}
Theoretically UpdateCallState could throw but we would hide this exception using that code and would treat only exceptions generated by CreateCall in a right way.
The question is, what is the right pattern for these situations so that we treat all the exceptions correctly?
You can always nest another try..catch inside the first catch and deal with it appropriately.
try
{
externalService.CreateCall(callParams);
}
catch (Exception ex)
{
_log.Error("Unexpected exception when trying execute an external code.", ex);
try
{
_callService.UpdateCallState(call, CallState.Disconnected, CallOutcome.Failed);
}
catch(Exception updateEx)
{
// do something here, don't just swallow the exception
}
throw; // this still rethrows the original exception
}
Break it up. Something like
if !TryCreateExternalCall(callParams)
{
_log.Error("Unexpected exception when trying execute an external code.", ex);
_callService.UpdateCallState(call, CallState.Disconnected, CallOutcome.Failed);
}
else
{
throw new ExternalServiceException(???);
}
TryCreateExternalCall should of course log the exception and stacktrace, before it swallows and returns false.
It is not a good practice to throw exception in Catch block.
The try, Catch suggest that
try
{
//make some changes. If something goes wrong go to Catch.
}
Catch(exception)
{
//I will clean the mess. Rollback the changes.
}
Catch the exception, only if you can handle the exception. Else bubble it up let the caller decide on what to do with the exception.
You should catch the most specific exception first, followed by the most general exceptions.
try
{
externalService.CreateCall(callParams);
}
catch (CreateCallExceptionType ccEx)
{
_callService.UpdateCallState(call, CallState.Disconnected, CallOutcome.Failed);
}
catch (Exception ex)
{
//do something
}
And then you could handle the UpdateCallState exception within the method.
What is the difference between
try { }
catch
{ throw; }
and
try { }
catch(Exception e)
{ throw e;}
?
And when should I use one or the other?
The constructions
try { ... }
catch () { ... } /* You can even omit the () here */
try { ... }
catch (Exception e) { ... }
are similar in that both will catch every exception thrown inside the try block (and, unless you are simply using this to log the exceptions, should be avoided). Now look at these:
try { ... }
catch ()
{
/* ... */
throw;
}
try { ... }
catch (Exception e)
{
/* ... */
throw;
}
try { ... }
catch (Exception e)
{
/* ... */
throw e;
}
The first and second try-catch blocks are EXACTLY the same thing, they simply rethrow the current exception, and that exception will keep its "source" and the stack trace.
The third try-catch block is different. When it throws the exception, it will change the source and the stack trace, so that it will appear that the exception has been thrown from this method, from that very line throw e on the method containing that try-catch block.
Which one should you use? It really depends on each case.
Let's say you have a Person class with a .Save() method that will persist it into a database. Let's say that your application executes the Person.Save() method somewhere. If your DB refuses to save the Person, then .Save() will throw an exception. Should you use throw or throw e in this case? Well, it depends.
What I prefer is doing:
try {
/* ... */
person.Save();
}
catch(DBException e) {
throw new InvalidPersonException(
"The person has an invalid state and could not be saved!",
e);
}
This should put the DBException as the "Inner Exception" of the newer exception being throw. So when you inspect this InvalidPersonException, the stack trace will contain info back to the Save method (that might be sufficient for you to solve the problem), but you still have access to the original exception if you need it.
As a final remark, when you are expecting an exception, you should really catch that one specific exception, and not a general Exception, ie, if you are expecting an InvalidPersonException you should prefer:
try { ... }
catch (InvalidPersonException e) { ... }
to
try { ... }
catch (Exception e) { ... }
The first preserves the stack trace while the second resets it. This means that if you use the second approach the stack trace of the exception will always start from this method and you will lose the original exception trace which could be disastrous for someone reading exception logs as he will never find out the original cause of the exception.
The second approach might be useful when you want to add additional information to the stack trace but it is used like this:
try
{
// do something
}
catch (Exception ex)
{
throw new Exception("Additional information...", ex);
}
There's a blog post discussing the differences.
You should use
try { }
catch(Exception e)
{ throw }
if you want to do something with the exception before re-throwing it (logging for example). The lonely throw preserves stack trace.
The difference between a parameterless catch and a catch(Exception e) is that you get a reference to the exception. From framework version 2 unmanaged exceptions are wrapped in a managed exception, so the parameterless exception is no longer useful for anything.
The difference between throw; and throw e; is that the first one is used to rethrow exceptions and the second one is used to throw a newly created exception. If you use the second one to rethrow an exception, it will treat it like a new exception and replace all stack information from where it was originally thrown.
So, you shold not use either of the alternatives in the question. You should not use the parameterless catch, and you should use throw; to rethrow an exception.
Also, in most cases you should use a more specific exception class than the base class for all exceptions. You should only catch the exceptions that you anticipate.
try {
...
} catch (IOException e) {
...
throw;
}
If you want to add any information when rethrowing the exception, you create a new exception with the original exception as an inner exception to preservere all information:
try {
...
} catch (IOException e) {
...
throw new ApplicationException("Some informative error message", e);
}