What is the recommended way to catch exceptions - c#

I have to do a code review and i got to a code part that addresses possibles exceptions. it looks to me that the developer coding works but i want to ask what is the usual and correct way to do that. What is the best way to do catch exceptions?
the coder wrote:
try
{ . . . }
catch (Exception ex)
{
if (ex is PlatformNotSupportedException)
{ //for the Windows version or edition that does not support.
// tracing
}
else if (ex is NotSupportedException || ex is IOException)
{ // for the NTFS not supported or EFS is not configured
// tracing
}
else
{
//report any exception as encrypt/decrypt
}
}
I thought that the book says that it should be:
catch (PlatformNotSupportedException pnse)
{
//for the Windows version or edition that does not support.
// tracing
}
catch (NotSupportedException nse)
{
// for the NTFS not supported or EFS is not configured
// tracing
}
catch (IOException ioe)
{
// tracing for IOE
}
catch (Exception e)
{
//report any exception as encrypt/decrypt
}

The second approach would be more preferred. However, there is tiny difference between proposed solution and current one. You'd need to refactor to a method, or copy the code in two places (NotSupportedException and IOException catch blocks), whilst current implementation handles it under the same if block.
So, if you want to follow the same approach, you can use when keyword to filter out certain types and more.
catch (PlatformNotSupportedException pnse)
{
// for the Windows version or edition that does not support.
// tracing
}
catch (Exception ex) when (ex is NotSupportedException || ex is IOException)
{
// for the NTFS not supported or EFS is not configured
// tracing
}
catch (Exception e)
{
//report any exception as encrypt/decrypt
}
If that's not mandatory, you can leave implementation as is

TLDR: Use the second form so that the compiler catches ordering errors.
The reason that you should use the second form is because then you will get a compile error if you attempt to handle the types in the wrong order.
For example, this will give you an actual compiler error:
try
{
throw new ArgumentOutOfRangeException();
}
catch (Exception)
{
Console.WriteLine("Caught 'Exception'");
}
// This gives a compile error:
// "Error CS0160 A previous catch clause already catches all exceptions of this or of a super type ('Exception')"
catch (SystemException)
{
Console.WriteLine("Caught 'SystemException'");
}
However, using if/else if will NOT cause a compile error, so the error goes unnoticed:
try
{
throw new ArgumentOutOfRangeException();
}
catch (Exception ex)
{
if (ex is Exception)
{
Console.WriteLine("Caught 'Exception'");
}
else if (ex is SystemException) // This will never be reached, but no compile error.
{
Console.WriteLine("Caught 'SystemException'");
}
}
Note, however, that tools such as Resharper will warn you for the second case.

this would be generic for all type of exception
try
{
.....code
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}

Related

Different catch in try-catch

What is difference between these types of catch, except that in first I can use e?
catch (Exception e)
{
//some code;
}
catch (Exception)
{
//some code;
}
catch
{
//some code;
}
try{
//do something
}catch{
//do something
}
This catch is executed, regardless of the exception.
try{
//do something
}catch (Exception) {
//do something
}
This catch is executed when a specific Exception is thrown
try{
//do something
}catch (Exception e) {
//do something
}
Same here, only that you have a reference to the Exception. That way, you have access to it.
Read more here.
Catch can catch different exception's types.
When you use the syntax catch(Exception) you are telling the compiler to write code that catches any kind of exceptions while, if you use a syntax like catch(InvalidOperationException), you are asking to catch a specific type of exception
To simplify things you can write catch without any type and this has the same meaning of catch(Exception)
try
{
// Uncomment this line to catch the generic exception
// throw new Exception("An exception occurred");
throw new InvalidOperationException("Operation x is not valid in this context");
}
// Comment the following lines to fall into the generic catch exception
catch (InvalidOperationException)
{
// But without the variable we cannot print out the message....
Console.WriteLine("An invalid operation has been catched");
}
catch (Exception)
{
Console.WriteLine("An exception raised");
}
You cannot use the syntax catch(Exception ex) in the same try catch where you don't specify the name of the variable for the same type of exception.
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
// Syntax error: CS0160: A previous catch clause already catches ......
catch (Exception)
{
Console.WriteLine("An exception raised");
}
Strangely enough this doesn't result in a syntax error, but in a simple warning
catch(Exception)
{
....
}
// Warning CS1058: A previous catch clause already catches ......
catch
{
....
}
Of course you shouldn't catch exceptions that you are not prepared to handle. If you do it just to expose a message you risk the correct functionality of your program. Usually you catch only specific exceptions that you are know how to handle to allow your program to continue. The only reason that I could find to catch all exceptions is when you write down the exception data in some kind of log file and then throw again the exception.
catch(Exception ex)
{
Logger.Error("Unexpected exception", ex);
throw; // NEVER throw ex;
}
Remember that it is really never required to write throw ex because you loose the stack trace of the exception and make very difficult to track down the exact error point.
See: Best practices for catching and re-throwing .NET exceptions
If your code throws an exception, then the catch Block will be thrown and you have access to it over e.
catch (Exception e)
{
//some code;
}
If your code throws an exception, then the catch Block will be thrown indepented from the exception type and you don’t have access to it.
catch
{
//some code;
}
If your code throws an exception, then the catch Block will be thrown depending from the exception type and you don’t have access to it.
catch (Exception)
{
//some code;
}
Instead of Exception you should use a more specific exception type!
let's check
in this code you can write e.Message for check Catch Message
catch (Exception e)
{
Console.WriteLine("Error Message is : " + e.Message);
}
but in this you just skip From Exception (All Exceptions) and you can add more Exceptions
catch (sqlExcetion)
{
//if your code have sqlEsception Get here
}
catch (Exception)
{
//if your code have any Exception Get here
}
and in this code you can create one catch and all catch go this
catch
{
//all catch get here
}
The minor difference between:
try{
//do something
}catch (Exception) {
//do something
}
and
try{
//do something
}catch (Exception e) {
//do something
}
is: (the second one will give)
The variable 'e' is declared but never used
Also, if the code is like this:
catch(Exception e) { throw e; }
the original stacktrace is gone. So, you have to do: catch(Exception e) { throw; }
to see the original stacktrace.

Catch Specific MySQL-Error (C#)

Is there way to catch a specific MySQL Error or more than one specific MySQL-Error?
I want to call a method if the error is "no selected database".
I am working with the MySQL-Connector / Net.
In your catch clause of your exception, you should be able to examine the Number property of the exception to determine which MySql exception was thrown. For example:
try
{
//Blah
}
catch (MySqlException ex)
{
if (ex.Number == 1046)
{
//Handle
}
throw;
}
catch (OtherExceptionType oet)
{
//Handle
}
If you are using C# 6.0, you can use exception filters.
try
{
//Blah
}
catch (MySqlException ex) when (ex.Number == 1046)
{
// Handle
}
catch (OtherExceptionType oet)
{
//Handle
}
The error number for "no database selected" is 1046 according to the documentation. Other error numbers are listed there as well.

Display Exception on try-catch clause

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);
}

Multiple-exception catches

Is possible to catch more then one exception in the same catch block?
try
{ }
catch(XamlException s | ArgumentException a)
{ }
Yes. If you catch a superclass, it will also catch all subclasses too:
try
{
// Some code
}
catch(Exception e)
{
// ...
}
If this catches more than you wanted then you can rethrow the exceptions that you didn't intend to catch by testing their type. If you do this, be careful to use the throw; syntax, and not throw e;. The latter syntax clobbers the stacktrace information.
But you can't catch two different types using the syntax you propose.
Not as succinctly as you are asking. One way would be to catch all exceptions and handle those two specially:
catch(Exception e)
{
if((e is SystemException) || (e is ArgumentException))
// handle, rethrow, etc.
else
throw;
}
Not being no C# guru however, this is standard in any oop language.
try
{
string s = null;
ProcessString(s);
}
// Most specific:
catch (InvalidCastException e) { out_one(e); }
catch (ArgumentNullException e) { out_two(e); }
// Least specific - anything will get caught
// here as all exceptions derive from this superclass
catch (Exception e)
{
// performance-wise, this would be better off positioned as
// a catch block of its own, calling a function (not forking an if)
if((e is SystemException) { out_two(); }
else { System..... }
}
In vb.net, it is possible to say Catch Ex As Exception When IsMyException(Ex), where IsMyException is any desired function which examines Ex and decides whether or not to catch it. The determination of whether or not to catch Ex is made before any inner Finally blocks run. Unfortunately, the makers of C# dislike the idea of allowing custom exception filters, perhaps because it would pollute the language with platform-specific details (most platforms could not support .net-style exception filters). Consequently, the best one can hope for in C# is to do something like:
void HandleThisOrThatException(BaseTypeOfThisThatTheOtherException)
{ ... }
...
// Catch ThisException or ThatException, but not TheOtherException
catch (ThisException ex) {HandleThisOrThatException(ex);}
catch (ThatException ex) {HandleThisOrThatException(ex);}
It's a bad example because any ArgumentException is also a SystemException, so catching all SystemExceptions would implicitly get the ArgumentExceptions as well.

Calling methods which might throw inside catch

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.

Categories