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.
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 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.
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.
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.
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;