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.
Related
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);
}
I would like to ask if I'm getting a right syntax in using the try and catch in asp.net
My code goes like this:
public ActionResult Add_RefPerson(rms_referred_person ref_person)
{
if (ModelState.IsValid) {
try
{
ref_person.rf_referreddate = Date();
ref_person.rf_createdby = getBadge();
ref_person.rf_updatedby = null;
ref_person.rf_updateddate = null;
ref_person.rf_isactive = true;
db.rms_referred_person.Add(ref_person);
db.SaveChanges();
return RedirectToAction("Index");
}
catch (Exception ex) {
throw ex;
}
}
return Content("<script type='text/javascript'>alert('Cannot be saved');</script>");
}
Is my try and catch in the right direction?
or should I use this one.
public ActionResult Add_RefPerson(rms_referred_person ref_person)
{
try
{
if (ModelState.IsValid) {
ref_person.rf_referreddate = Date();
ref_person.rf_createdby = getBadge();
ref_person.rf_updatedby = null;
ref_person.rf_updateddate = null;
ref_person.rf_isactive = true;
db.rms_referred_person.Add(ref_person);
db.SaveChanges();
return RedirectToAction("Index");
}
}
catch (Exception ex) {
throw ex;
}
return Content("<script type='text/javascript'>alert('Cannot be saved');</script>");
}
Thanks a lot.
That is the correct syntax to catch all exceptions; however it is a pretty bad antipattern. This catches ex and immediately throws it again, clobbering the entire stack trace. If rethrowing is desired, write throw;
In this case you do not want to throw at all, so empty catch might be correct. Consider returning a bit more information about what went wrong, which would require placing the error return in the catch clause itself.
2nd option is safer as it covers ModelState check too. Also, throw ex; is not a great idea. you will not get complete stack trace. use throw;
try
{
if (ModelState.IsValid) {
ref_person.rf_referreddate = Date();
ref_person.rf_createdby = getBadge();
ref_person.rf_updatedby = null;
ref_person.rf_updateddate = null;
ref_person.rf_isactive = true;
db.rms_referred_person.Add(ref_person);
db.SaveChanges();
return RedirectToAction("Index");
}
}
catch (Exception ex) {
throw ex;
}
The only difference is that the latter one will catch any exceptions in the
if (ModelState.IsValid)
line. Unless you think that line might actually throw an exception, they're identical.
You might also want to think more about casting such a wide net for exceptions (i.e., narrow down what actual exceptions you want to handle). The idea is to handle what you can and let everything else through for the upper layers to handle.
In addition, rethrowing an exception is best done with throw on its own rather than throw ex. The former preserves information that the latter will lose.
However, since you're not actually doing anything with the exception other than passing it up the tree, there's little point in catching it in the first place. Just execute the commands, if you get an exception, a higher level exception handler should take care of it without you messing around with try..catch.
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.
I am wondering can try..catch force execution to go into the catch and run code in there?
here example code:
try {
if (AnyConditionTrue) {
// run some code
}
else {
// go catch
}
} catch (Exception) {
// run some code here...
}
try{
if (AnyConditionTrue){
//run some code
}
else{
throw new Exception();
}
}
catch(){
//run some code here...
}
But like Yuck has stated, I wouldn't recommend this. You should take a step back at your design and what you're looking to accomplish. There's a better way to do it (i.e. with normal conditional flow, instead of exception handling).
Rather than throwing an Exception in the else, I would recommend extracting the code from your catch into a method and call that from your else
try
{
if (AnyConditionTrue)
{
MethodWhenTrue();
}
else
{
HandleError();
}
}
catch(Exception ex)
{
HandleError();
}
Yes, you have to throw exception :
try
{
throw new Exception("hello");
}
catch (Exception)
{
//run some code here...
}
An effective way to throw an Exception and also jump to Catch as so:
try
{
throw new Exception("Exception Message");
}
catch (Exception e)
{
// after the throw, you will land here
}
if(conditiontrue)
{
}
else{
throw new Exception();
}
Yes, if you throw the exception that you intend to catch from within the try, it will be caught in the catch section.
I have to ask you why you would want to do this though? Exception handling is not meant to be a substitute for control flow.
I think what you want is a finally block: http://msdn.microsoft.com/en-us/library/zwc8s4fz(v=vs.80).aspx
see this
try
{
doSomething();
}
catch
{
catchSomething();
throw an error
}
finally
{
alwaysDoThis();
}
This is different if/when you do this:
try
{
doSomething();
}
catch
{
catchSomething();
throw an error
}
alwaysDoThis();// will not run on error (in the catch) condition
the the this last instance, if an error occurs, the catch will execute but NOT the alwaysDoThis();. Of course you can still have multiple catch as always.
As cadrel said, but pass through an Exception to provide more feedback, which will be shown in the innerException:
try
{
if (AnyConditionTrue)
{
MethodWhenTrue();
}
else
{
HandleError(new Exception("AnyCondition is not true"));
}
}
catch (Exception ex)
{
HandleError(ex);
}
...
private void HandleError(Exception ex) {
throw new ApplicationException("Failure!", ex);
}
public class CustomException: Exception
{
public CustomException(string message)
: base(message) { }
}
//
if(something == anything)
{
throw new CustomException(" custom text message");
}
you can try this
You could throw an exception to force a catch
throw new Exception(...);
why are you catching an exception? Why not just run the code in your "else" block? If you MUST do it that way, just throw a new exception
throw new Exception();
Slight resurrection, but I wanted to add both a sample (primarily like others) and a use case.
public int GetValueNum(string name)
{
int _ret = 0;
try
{
Control c = (extendedControls.Single(s => s.ValueName == name) as Control);
if (c.GetType() == typeof(ExtendedNumericUpDown))
_ret = (int)((ExtendedNumericUpDown)c).Value;
else
throw new Exception();
}
catch
{
throw new InvalidCastException(String.Format("Invalid cast fetching .Value value for {0}.\nExtendedControllerListener.GetValueNum()", name));
}
return _ret;
}
In my case, I have custom controls - a handful of controls that use a base Windows.Forms control, but add two bools and a string for tracking, and also automatically get registered to a Singleton List<T> so they can be properly fetched without drilling down through control containers (it's a tabbed form).
In this case, I'm creating some methods to easily get values (.Value, .Text, .Checked, .Enabled) by a name string. In the case of .Value, not all Control objects have it. If the extended control is not of type ExtendedNumericUpDown, it IS an InvalidCastException as the method should not be called against that type of control. This isn't flow, but the prescribed usage of invalid cast. Since Control doesn't naturally have a .Value property, Visual Studio won't let me just force an attempt and fail after.
When C# throws an exception, it can have an inner exception. What I want to do is get the inner-most exception, or in other words, the leaf exception that doesn't have an inner exception. I can do this in a while loop:
while (e.InnerException != null)
{
e = e.InnerException;
}
But I was wondering if there was some one-liner I could use to do this instead.
Oneliner :)
while (e.InnerException != null) e = e.InnerException;
Obviously, you can't make it any simpler.
As said in this answer by Glenn McElhoe, it's the only reliable way.
I believe Exception.GetBaseException() does the same thing as these solutions.
Caveat: From various comments we've figured out it doesn't always literally do the same thing, and in some cases the recursive/iterating solution will get you further. It is usually the innermost exception, which is disappointingly inconsistent, thanks to certain types of Exceptions that override the default. However if you catch specific types of exceptions and make reasonably sure they're not oddballs (like AggregateException) then I would expect it gets the legitimate innermost/earliest exception.
Looping through InnerExceptions is the only reliable way.
If the caught exception is an AggregateException, then GetBaseException() returns only the innermost AggregateException.
http://msdn.microsoft.com/en-us/library/system.aggregateexception.getbaseexception.aspx
If you don't know how deep the inner exceptions are nested, there is no way around a loop or recursion.
Of course, you can define an extension method that abstracts this away:
public static class ExceptionExtensions
{
public static Exception GetInnermostException(this Exception e)
{
if (e == null)
{
throw new ArgumentNullException("e");
}
while (e.InnerException != null)
{
e = e.InnerException;
}
return e;
}
}
I know this is an old post, but I'm surprised nobody suggested GetBaseException() which is a method on the Exception class:
catch (Exception x)
{
var baseException = x.GetBaseException();
}
This has been around since .NET 1.1. Documentation here:
http://msdn.microsoft.com/en-us/library/system.exception.getbaseexception(v=vs.71).aspx
Sometimes you might have many inner exceptions (many bubbled exceptions).
In which case you might want to do:
List<Exception> es = new List<Exception>();
while(e.InnerException != null)
{
es.add(e.InnerException);
e = e.InnerException
}
You could use recursion to create a method in a utility class somewhere.
public Exception GetFirstException(Exception ex)
{
if(ex.InnerException == null) { return ex; } // end case
else { return GetFirstException(ex.InnerException); } // recurse
}
Use:
try
{
// some code here
}
catch (Exception ex)
{
Exception baseException = GetFirstException(ex);
}
The extension method suggested (good idea #dtb)
public static Exception GetFirstException(this Exception ex)
{
if(ex.InnerException == null) { return ex; } // end case
else { return GetFirstException(ex.InnerException); } // recurse
}
Use:
try
{
// some code here
}
catch (Exception ex)
{
Exception baseException = ex.GetFirstException();
}
Not quite one line but close:
Func<Exception, Exception> last = null;
last = e => e.InnerException == null ? e : last(e.InnerException);
In fact is so simple, you could use Exception.GetBaseException()
Try
//Your code
Catch ex As Exception
MessageBox.Show(ex.GetBaseException().Message, My.Settings.MsgBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
End Try
You have to loop, and having to loop, it's cleaner to move the loop into a separate function.
I created an extension method to deal with this. It returns a list of all of the inner exceptions of the specified type, chasing down Exception.InnerException and AggregateException.InnerExceptions.
In my particular problem, chasing down the inner exceptions was more complicated than usual, because the exceptions were being thrown by the constructors of classes that were being invoked through reflection. The exception we were catching had an InnerException of type TargetInvocationException, and the exceptions we actually needed to look at were buried deep in the tree.
public static class ExceptionExtensions
{
public static IEnumerable<T> innerExceptions<T>(this Exception ex)
where T : Exception
{
var rVal = new List<T>();
Action<Exception> lambda = null;
lambda = (x) =>
{
var xt = x as T;
if (xt != null)
rVal.Add(xt);
if (x.InnerException != null)
lambda(x.InnerException);
var ax = x as AggregateException;
if (ax != null)
{
foreach (var aix in ax.InnerExceptions)
lambda(aix);
}
};
lambda(ex);
return rVal;
}
}
Usage is pretty simple. If, for example, you want to know if we encountered a
catch (Exception ex)
{
var myExes = ex.innerExceptions<MyException>();
if (myExes.Any(x => x.Message.StartsWith("Encountered my specific error")))
{
// ...
}
}
I ran into this and wanted to be able to list all of the exception messages from the exception "stack". So, I came up with this.
public static string GetExceptionMessages(Exception ex)
{
if (ex.InnerException is null)
return ex.Message;
else return $"{ex.Message}\n{GetExceptionMessages(ex.InnerException)}";
}
Another way you could do it is by calling GetBaseException() twice:
Exception innermostException = e.GetBaseException().GetBaseException();
This works because if it is an AggregateException, the first call gets you to the innermost non-AggregateException then the second call gets you to the innermost exception of that exception. If the first exception is not an AggregateException, then the second call just returns the same exception.