How do I catch the right exception? - c#

I have the method below. Anytime myResult variable is empty, I get a 500 internal server
error. Various scenarios can make myResult empty.
How do I catch the right exception and not a 500 internal server error ?
try
{
var myResult = await _myRepository.GetDataAsync(Id);
if (!myResult.Any())
{
throw new ArgumentException("Unable to retrieve record");
}
return myResult;
}
catch (HttpProxyException ex)
{
string errorMessage = ex.Message.ToString();
throw new ArgumentException(errorMessage);
}

I suspect your _myRepository.GetDataAsync(Id); to throw the HttpProxyException. So you can't check if myResult is empty because the error throw earlier.
You can adapt your code as follow :
var myResult;
try
{
myResult = await _myRepository.GetDataAsync(Id);
catch (HttpProxyException ex)
{
string errorMessage = ex.Message.ToString();
throw new ArgumentException(errorMessage);
}
if (!myResult.Any())
{
throw new ArgumentException("Unable to retrieve record");
}
return myResult;
In this scenario, the 500 internal server error throw only when you try to get the data but received the error. If you succeed to get the result but there is no datas, you throw your custom exception.

As it stands, your code will only catch HttyPRoxyException type exceptions. So your ArgumentException exception it won't be caught.
But you can have multiple catch clauses to handle different exception types. They are evaluated in order from first to last, and the first one with a matching signature will handle it.
For example you could use
try
{
var myResult = await _myRepository.GetDataAsync(Id);
if (!myResult.Any())
{
throw new ArgumentException("Unable to retrieve record");
}
return myResult;
}
catch (HttpProxyException ex)
{
string errorMessage = ex.Message.ToString();
throw new ArgumentException(errorMessage);
}
catch (ArgumentException ex)
{
//Do something different here;
}
You could also put a generic catch at the end to trap any other Exception types, if desired.
catch (Exception ex)
{
//Do whatever;
}
NB: One thing to be aware of is that by throwing a new Exception in the Catch, you will be losing the earlier stack trace. This can make it harder to pinpoint the exact location of the offending code.
One way to help with this problem is to include the original exception with the new one, i.e.
catch (HttpProxyException ex)
{
string errorMessage = ex.Message.ToString();
throw new ArgumentException(errorMessage, ex);
}

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.

Two Methods That Throws Exceptions How To Differentiate between them

I have a try catch block that surrounds two methods that can each throw ArgumentException.
I want to differentiate between the exceptions, so that I can return better error message for the user.
What will be the best way to do it? (I want to refrain from surrounding it with two separate try catch blocks).
try
{
var store = storeFactory.Create(id); // Can Throw ArgumentException
var order = await store.GetOrderAsync(orderId); //Can Throw ArgumentException
return Ok(order);
}
catch (ArgumentException ex)
{
//TODO: How To Tell Which Methods Throw The Exception (Create Or GetOrderAsync)
return NotFound("Store Id Was Not Found");
return NotFound("Order Id Was Not Found");
}
You can simply separate the try block into two try blocks:
try
{
var store = storeFactory.Create(id); // Can Throw ArgumentException
try
{
var order = await store.GetOrderAsync(orderId); //Can Throw ArgumentException
return Ok(order);
}
catch ( ArgumentException ex )
{
return NotFound("Order Id Was Not Found");
}
}
catch (ArgumentException ex)
{
//TODO: How To Tell Which Methods Throw The Exception (Create Or GetOrderAsync)
return NotFound("Store Id Was Not Found");
}
Even better solution however would be to create a new type of exception for both cases, for example:
public class OrderNotFoundException : Exception
and
public class StoreNotFoundException : Exception
And then modify your methods to throw these descriptive errors instead.

Catch InvalidOperationException with empty structure

I am trying to catch the InvalidOperationException that can sometimes occur when declaring variables. The following code doesn't work however. Probably because I don't really know how you catch an exception.
public override void Download()
{
try
{
var t = (ForumThread)Globals.Db.Thread.Get(_extIdForumThread, _idF);
try
{
throw new InvalidOperationException();
}
catch (InvalidOperationException exception)
{
return;
}
catch (Exception exception)
{
throw;
}
}
}
Any help at all would be very appreciated.
You don't need to throw the exception yourself. Just have:
try
{
var t = (ForumThread)Globals.Db.Thread.Get(_extIdForumThread, _idF);
}
catch (InvalidOperationException exception)
{
// Error logging, post processing etc.
return;
}
You shouldn't really be catching the general exception either unless you have a really good reason to - i.e. your application cannot crash, but if you do you need to be able to recover from it.

Throwing a custom exception inside try catch

If I have some code inside a big try catch which eventually catches an OracleException and a general Exception then I can't throw any custom exception inside the try catch can I, as it gets caught by the general Exception.
What am I supposed to do in this instance?
Thanks
try
{
// some code
if(a==b)
{
throw new MyCustomException(ex);
}
}
catch(OracleException ex)
{
...
}
catch(Exception ex)
{
...
}
Do you mean that you want to throw a custom exception that isn't caught by the catch-all Exception block?
If this is the case, then try this:
try
{
throw new MyCustomException();
}
catch (OracleException ex)
{
// Handle me...
}
catch (MyCustomException)
{
// Important: NOT `throw ex` (to preserve the stack trace)
throw;
}
catch (Exception ex)
{
// Handle me...
}
Any exception of type MyCustomException will be caught by the second catch (rather than by the 3rd catch) and then rethrown.
Note that it's generally bad practice to do catch (Exception) - this is a good example of why. I definitely suggest that rather than doing the above, you simply refactor so that you are no longer catching Exception, which would be a far neater solution.
check this:
try
{
...
}
catch()
{
throw new Execption("I'M A NEW EXCEPTION")
}
finally
{
...
}
Can't you simply add a catch clause with your custom exception?
try
{
//Lots of code
}
catch (OracleException)
{
}
catch (MyCustomException)
{
}
catch (Exception)
{
}
Try this
catch(OracleException ex)
{
throw new MyCustomException(
"MyCustomEX error: Unable to ......", ex);
}

Can you catch more than one type of exception with each block? [duplicate]

This question already has answers here:
Catch multiple exceptions at once?
(29 answers)
Closed 9 years ago.
This question is close to what I want to do, but not quite there.
Is there a way to simplify the following code?
private bool ValidDirectory(string directory)
{
if (!Directory.Exists(directory))
{
if (MessageBox.Show(directory + " does not exist. Do you wish to create it?", this.Text)
== DialogResult.OK)
{
try
{
Directory.CreateDirectory(directory);
return true;
}
catch (IOException ex)
{
lblBpsError.Text = ex.Message;
}
catch (UnauthorizedAccessException ex)
{
lblBpsError.Text = ex.Message;
}
catch (PathTooLongException ex)
{
lblBpsError.Text = ex.Message;
}
catch (DirectoryNotFoundException ex)
{
lblBpsError.Text = ex.Message;
}
catch (NotSupportedException ex)
{
lblBpsError.Text = ex.Message;
}
}
}
return false;
}
It seems a waste, and if I later want to change how I report an error back to the user, or perhaps I want to log these errors, or whatever, then I've got to change 5 different catch blocks. Am I missing something, or is this blatantly against code-reuse?
Am I just trying to be (too) lazy?
You can use :
catch (SystemException ex)
{
if( (ex is IOException)
|| (ex is UnauthorizedAccessException )
// These are redundant
// || (ex is PathTooLongException )
// || (ex is DirectoryNotFoundException )
|| (ex is NotSupportedException )
)
lblBpsError.Text = ex.Message;
else
throw;
}
If the exceptions share a common super-class then you can just catch the superclass.
Yes, you're trying to be lazy, but laziness is one of the virtues of a programmer, so that's good.
As for your question: There is no way I am aware of, but there are some workarounds available:
Give the Exceptions a common ancestor. I think this won't be possible in your case, since they seem to be builtin.
Catch the most generic exception you can.
Move the handling code into its own function and call that from each catch block.
This is annoying, and other answers have suggested good workarounds (I'd use #Lotfi's).
However this behaviour is a requirement given the type-safety of C#.
Suppose you could do this:
try
{
Directory.CreateDirectory(directory);
return true;
}
catch (IOException,
UnauthorizedAccessException,
PathTooLongException,
DirectoryNotFoundException,
NotSupportedException ex)
{
lblBpsError.Text = ex.Message;
}
Now what type is ex? They all have .Message because they inherit System.Exception, but try accessing any of their other properties and you have a problem.
Its also important to note that when catching more then one type of exception they should be order by most specify to most general. The Exception will find the first one in the list that it matches and throw that error, none of the other errors will be thrown.
Just for completeness’ sake:
In VB, you could use conditional exception handling:
Try
…
Catch ex As Exception When TypeOf ex Is MyException OrElse _
TypeOf ex Is AnotherExecption
…
End Try
Such a Catch block would only get entered for the specified exceptions – unlike in C#.
Perhaps a future version of C# will offer a similar feature (after all, there's a specific IL instruction for that code).
MSDN: How to: Filter Errors in a Catch Block in Visual Basic
Check out the The Exception Handling Application Block from EntLib. They articulate a very nice policy and configuration based exception handling methodology that avoids large conditional logic blocks.
You can catch a base class exception (all your exceptions derive from SystemException):
try
{
Directory.CreateDirectory(directory);
return true;
}
catch (SystemException ex)
{
lblBpsError.Text = ex.Message;
}
But then you may end up catching exceptions you don't want to catch.
You can do
ex.GetType()
see http://msdn.microsoft.com/en-us/library/system.exception.gettype.aspx
EDIT
try
{
Directory.CreateDirectory(directory);
return true;
}
catch (Exception ex)
{ switch(ex.GetType())
case .....
case ..........
blBpsError.Text = ex.Message;
}
I understand some of these exceptions may not be foreseeable but where possible try to implement your own "pre-emptive" logic. Exceptions are expensive, though in this case probably not a deal breaker.
For example, use Directory.GetAccessControl(...) rather than relying on an UnauthorizedAccessException to be thrown.
You could use delegates, this will do what you want:
EDIT: simplified a bit
static void Main(string[] args)
{
TryCatch(() => { throw new NullReferenceException(); },
new [] { typeof(AbandonedMutexException), typeof(ArgumentException), typeof(NullReferenceException) },
ex => Console.WriteLine(ex.Message));
}
public static void TryCatch(Action action, Type[] exceptions, Action<Exception> catchBlock)
{
try
{
action();
}
catch (Exception ex)
{
if(exceptions.Any(p => ex.GetType() == p))
{
catchBlock(ex);
}
else
{
throw;
}
}
}
Your particular try/catch would be:
bool ret;
TryCatch(
() =>
{
Directory.CreateDirectory(directory);
ret = true;
},
new[]
{
typeof (IOException), typeof (UnauthorizedAccessException), typeof (PathTooLongException),
typeof (DirectoryNotFoundException), typeof (NotSupportedException)
},
ex => lblBpsError.Text = ex.Message
);
return ret;

Categories