I have an application that can sometimes throw an exception, most of these are handled but I want the unhandled ones to be recoverable. So I'm trying to invoke the method that caused the exception by using the exception's targetsite like so:
Exception ex = Global.ThrownException;
MethodBase mB = ex.TargetSite;
try
{
mB.Invoke(mB, null);
}
catch(Exception exc)
{
System.Windows.MessageBox.Show(exc.Message);
}
I'm doing this to make sure that the exception was a one time error before showing the window to the user again.
The test method (and the exception targetsite) I'm trying to invoke is this:
public void testMethod()
{
throw new System.IO.IOException("test");
}
When I run this, an exception is thrown with the message "Object does not match target type" but since testMethod doesn't have any parameters this shouldn't happen.
Any ideas?
Related
I have a function "ReturnString":
public static string ReturnString(string sa, string sb)
{
try
{
...
...
return "xyz";
}
catch (Exception ex)
{
throw new clsException(ex.Message);
}
}
it is call by more than 600 times from other more then 40 classes and win farms Mean's it has more than 600 references in more then 40 classes and win farms.
When Exception thrown by it, I want to know what is the it's last calling ref. when exception happen?
Please help me to solve this without changing function arguments.
You should initialize an instance of StackTrace class -
https://msdn.microsoft.com/en-us/library/system.diagnostics.stacktrace(v=vs.110).aspx
Then, get the first StackFrame -
https://msdn.microsoft.com/en-us/library/system.diagnostics.stackframe(v=vs.110).aspx
Finally, get the MethodBase of this frame; Its "Name" property is what you need -
https://msdn.microsoft.com/en-us/library/system.reflection.methodbase(v=vs.110).aspx
Try this:
public static string ReturnString(string sa, string sb)
{
try
{
//...
//...
return "xyz";
}
catch (Exception ex)
{
StackTrace oStackTrace = new StackTrace();
string sMethodName = oStackTrace.GetFrame(1).GetMethod().Name;
//It's not a good practice to keep only the error message (you may need other exception details later)
throw new clsException(string.Format("{0}: {1}", sMethodName, ex.Message));
}
}
Your problem is here:
throw new clsException(ex.Message);
As others have mentioned, ex already contains the info you want inside the StackTrace property (check this link for more info).
But when you throw a new exception, you are only throwing the message, and ignoring all the info you want to get.
Just throw without a new exception, or include ex as the inner exception of your clsException.
I want to know what is the it's last calling ref. when exception
happen?
Then check the exception StackTrace, that will let you know the entire call stack and the latest one responsible for exception. Also the innerException property if any.
Check the documentation on Exception class. It has a property StackTrace which you should check.
In your case, the exception object should have it ex.StackTrace
You may also want to get the TargetSite property value from your exception object saying ex.TargetSite
Is there a way to override the message of an exception?
I don't want to make a custom exception but to override the message of an existing exception.
For example:
Every time when a ArgumentOutOfRangeException is thrown, I'd like it to contain my message instead of the default one.
Is it possible?
For exceptions you're throwing, you can just pass the message in to the constructor:
throw new ArgumentOutOfRangeException("name", "My custom message");
Note that here, name is the name of the parameter that caused the problem. In C# 6, you should use the nameof operator to make this refactoring-safe:
public void Foo(int x)
{
if (x > 10)
{
throw new ArgumentOutOfRangeException(nameof(x), "That's too big");
}
}
You can't modify the message of an exception thrown by other code, but you can catch the exception and rethrow another one:
try
{
...
}
catch (FooException e)
{
// Keep the original exception
throw new BarException("Some message", e);
}
I would try to avoid doing this too much though. If you're considering showing exception messages to users, I would generally shy away from that - they're really aimed at developers. As an example, the ArgumentOutOfRangeException you suggested should generally indicate a bug in your code rather than some external condition (like a network failure or whatever) - the user isn't going to be able to do anything about that bug; it's something you should fix. A network failure or something similar is at least more reasonable for the user to take action about, but frankly it's often not going to be clear what the chain of events is.
The Exception.Message property is declared read-only, so no, you cannot change the Message of a pre-existing Exception object. (The same applies to derived exception types.)
But you can set the message text of an exception you're throw-ing yourself: usually, you pass the message text to the exception constructor:
throw new ArgumentException("Frobbled arguments are not accepted", paramName: …);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
When you define your own exception types, you should follow this protocol; see the section at the end of this answer.
You want to change an existing exception object's Message — Alternatives:
Catch the original exception and derive a new exception from it that is identical except for the message:
…
catch (ArgumentException ex)
{
throw new ArgumentException("New message text", paramName: ex.ParamName);
}
This is in general not a terribly good idea, because you might lose state data contained in ex (such as its stack trace and InnerException). But it might work just fine in this scenario.
Wrap the exception in a new exception so that it becomes the InnerException:
…
catch (ArgumentException ex)
{
throw new ArgumentException("New message text", innerException: ex);
}
This is better, because all the original exception's state is preserved. However, in the particular case of ArgumentException it is not obvious at all that the actual exception information is contained in the InnerException.
How to make sure your own exception classes allow setting the message et al.:
When you define a new exception type, it's important for the reasons mentioned above to define constructors that accept a message text and/or an inner exception. So a custom exception class would have at least these constructors:
class MyCustomException : Exception
{
public MyCustomException() : base() { }
public MyCustomException(string message) : base(message) { }
public MyCustomException(string message, Exception innerException) : base(message, innerException) { }
public MyCustomException(string message) : base(message) { }
}
You can use try .. . catch
try
{
//Code here regarding array indexing
}
catch (ArgumentOutOfRangeException ex)
{
throw new ArgumentOutOfRangeException("exception", "New Custom Message");
//Or show new message
MessageBox.Show("Your custom Message");
}
I have created few custom exception class
public class CreateNewUserWebException : Exception
{
public CreateNewUserWebException(string email): base(
string.Format("[{0}] - User could not be added.", email))
{
}
}
public class CreateNewUserEntityFrameworkException : System.Data.DataException
{
public CreateNewUserEntityFrameworkException(string email)
: base(
string.Format("[{0}] - User could not be added.", email))
{
}
}
and here is my controller code
try
{
var user = _createUserModule.CreateUser(model);
CookieManager.SetAuthenticationCookie(user, model.Email, rememberMe: false);
return RedirectToAction("Index", "Bugs");
}
catch (CreateNewUserEntityFrameworkException exception)
{
this.ModelState.AddModelError("", "Some error occured while registering you on our sytem. Please try again later.");
Elmah.ErrorSignal.FromCurrentContext().Raise(exception);
}
catch (CreateNewUserWebException exception)
{
this.ModelState.AddModelError("", "Some error occured while registering you on our sytem. Please try again later.");
Elmah.ErrorSignal.FromCurrentContext().Raise(exception);
}
catch(Exception exception)
{
this.ModelState.AddModelError("", "Some error occured while registering you on our sytem. Please try again later.");
Elmah.ErrorSignal.FromCurrentContext().Raise(exception);
}
I have purposely fully induced an primary key violation exception which is
but exception is not catched by my custom exception class. It is not caught by the last exception catch block.
I cannot understand why so. Can some one help me out on this please.
The part you've highlighted in the debugger is the inner exception. That isn't used by the CLR to determine which catch block to enter. The outer exception is just a DbUpdateException - which you haven't specified a particular catch block for.
Even the inner exception is just a DataException - it's not an instance of your custom exception.
You haven't shown any code which actually throws your exception - are you sure it's being used at all? What code have you written to tell EF to throw your exception rather than the exception it would otherwise throw?
(Given your comments, I'm not sure you quite understand exception handling. Creating a custom exception doesn't somehow let you catch an instance of that without it being thrown - something still has to throw an instance of that exception before it's any use.)
This question already has answers here:
Why is TargetInvocationException treated as uncaught by the IDE?
(2 answers)
Closed 8 years ago.
When using property reflection to SetValue, the property throws a TargetInvocationException. However, since the call to SetValue is an invocation, the exception is caught and not handled in the property. Is there way to handle the Target Exception in the property and have it ONLY thrown in the main program?
I want this throw to be as if I just made a method call, not an invocation.
Edit for clarification:
The problem I am having is that within the reflect class, I am getting a debug message that says "Exception was unhandled by user code". I have to 'continue' with the debug session and the inner exception is the 'real' exception. Is this just to be expected? I dont want to get warned (and I dont want to hide warnings), I want the code to fix the warning.
public class reflect
{
private int _i;
public int i
{
get { return _i; }
set
{
try{throw new Exception("THROWN");}
catch (Exception ex)
{ // Caught here ex.Message is "THROWN"
throw ex; // Unhandled exception error DONT WANT THIS
}
}
}
}
class Program
{
static void Main(string[] args)
{
reflect r = new reflect();
try
{
r.GetType().GetProperty("i").SetValue(r, 3, null);
}
catch(Exception ex)
{ // Caught here, Message "Exception has been thrown by the target of an invocation"
// InnerMessage "THROWN"
// WANT THIS Exception, but I want the Message to be "THROWN"
}
}
}
You need the InnerException:
catch(Exception ex)
{
if (ex.InnerException != null)
{
Console.WriteLine(ex.InnerException.Message);
}
}
This isn't specific to reflection - it's the general pattern for any exception which was caused by another. (TypeInitializationException for example.)
Sorry, can't comment yet. Two things:
1) why are you first catching ex in your reflection class and then throwing it again? This shouldn't be the problem, though.
2) I think you are getting your exception. Check the "Exception has been thrown"'s inner exception.
What is the difference between
try { ... }
catch{ throw }
and
try{ ... }
catch(Exception e) {throw new Exception(e.message) }
regardless that the second shows a message.
throw; rethrows the original exception and preserves its original stack trace.
throw ex; throws the original exception but resets the stack trace, destroying all stack trace information until your catch block.
NEVER write throw ex;
throw new Exception(ex.Message); is even worse. It creates a brand new Exception instance, losing the original stack trace of the exception, as well as its type. (eg, IOException).
In addition, some exceptions hold additional information (eg, ArgumentException.ParamName).
throw new Exception(ex.Message); will destroy this information too.
In certain cases, you may want to wrap all exceptions in a custom exception object, so that you can provide additional information about what the code was doing when the exception was thrown.
To do this, define a new class that inherits Exception, add all four exception constructors, and optionally an additional constructor that takes an InnerException as well as additional information, and throw your new exception class, passing ex as the InnerException parameter. By passing the original InnerException, you preserve all of the original exception's properties, including the stack trace.
The first preserves the original stacktrace:
try { ... }
catch
{
// Do something.
throw;
}
The second allows you to change the type of the exception and/or the message and other data:
try { ... } catch (Exception e)
{
throw new BarException("Something broke!");
}
There's also a third way where you pass an inner exception:
try { ... }
catch (FooException e) {
throw new BarException("foo", e);
}
I'd recommend using:
the first if you want to do some cleanup in error situation without destroying information or adding information about the error.
the third if you want to add more information about the error.
the second if you want to hide information (from untrusted users).
One other point that I didn't see anyone make:
If you don't do anything in your catch {} block, having a try...catch is pointless. I see this all the time:
try
{
//Code here
}
catch
{
throw;
}
Or worse:
try
{
//Code here
}
catch(Exception ex)
{
throw ex;
}
Worst yet:
try
{
//Code here
}
catch(Exception ex)
{
throw new System.Exception(ex.Message);
}
Throwing a new Exception blows away the current stack trace.
throw; will retain the original stack trace and is almost always more useful. The exception to that rule is when you want to wrap the Exception in a custom Exception of your own. You should then do:
catch(Exception e)
{
throw new CustomException(customMessage, e);
}
None of the answers here show the difference, which could be helpful for folks struggling to understand the difference. Consider this sample code:
using System;
using System.Collections.Generic;
namespace ExceptionDemo
{
class Program
{
static void Main(string[] args)
{
void fail()
{
(null as string).Trim();
}
void bareThrow()
{
try
{
fail();
}
catch (Exception e)
{
throw;
}
}
void rethrow()
{
try
{
fail();
}
catch (Exception e)
{
throw e;
}
}
void innerThrow()
{
try
{
fail();
}
catch (Exception e)
{
throw new Exception("outer", e);
}
}
var cases = new Dictionary<string, Action>()
{
{ "Bare Throw:", bareThrow },
{ "Rethrow", rethrow },
{ "Inner Throw", innerThrow }
};
foreach (var c in cases)
{
Console.WriteLine(c.Key);
Console.WriteLine(new string('-', 40));
try
{
c.Value();
} catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
}
}
Which generates the following output:
Bare Throw:
----------------------------------------
System.NullReferenceException: Object reference not set to an instance of an object.
at ExceptionDemo.Program.<Main>g__fail|0_0() in C:\...\ExceptionDemo\Program.cs:line 12
at ExceptionDemo.Program.<>c.<Main>g__bareThrow|0_1() in C:\...\ExceptionDemo\Program.cs:line 19
at ExceptionDemo.Program.Main(String[] args) in C:\...\ExceptionDemo\Program.cs:line 64
Rethrow
----------------------------------------
System.NullReferenceException: Object reference not set to an instance of an object.
at ExceptionDemo.Program.<>c.<Main>g__rethrow|0_2() in C:\...\ExceptionDemo\Program.cs:line 35
at ExceptionDemo.Program.Main(String[] args) in C:\...\ExceptionDemo\Program.cs:line 64
Inner Throw
----------------------------------------
System.Exception: outer ---> System.NullReferenceException: Object reference not set to an instance of an object.
at ExceptionDemo.Program.<Main>g__fail|0_0() in C:\...\ExceptionDemo\Program.cs:line 12
at ExceptionDemo.Program.<>c.<Main>g__innerThrow|0_3() in C:\...\ExceptionDemo\Program.cs:line 43
--- End of inner exception stack trace ---
at ExceptionDemo.Program.<>c.<Main>g__innerThrow|0_3() in C:\...\ExceptionDemo\Program.cs:line 47
at ExceptionDemo.Program.Main(String[] args) in C:\...\ExceptionDemo\Program.cs:line 64
The bare throw, as indicated in the previous answers, clearly shows both the original line of code that failed (line 12) as well as the two other points active in the call stack when the exception occurred (lines 19 and 64).
The output of the rethrow case shows why it's a problem. When the exception is rethrown like this the exception won't include the original stack information. Note that only the throw e (line 35) and outermost call stack point (line 64) are included. It would be difficult to track down the fail() method as the source of the problem if you throw exceptions this way.
The last case (innerThrow) is most elaborate and includes more information than either of the above. Since we're instantiating a new exception we get the chance to add contextual information (the "outer" message, here but we can also add to the .Data dictionary on the new exception) as well as preserving all of the information in the original exception (including help links, data dictionary, etc.).
throw rethrows the caught exception, retaining the stack trace, while throw new Exception loses some of the details of the caught exception.
You would normally use throw by itself to log an exception without fully handling it at that point.
BlackWasp has a good article sufficiently titled Throwing Exceptions in C#.
throw is for rethrowing a caught exception. This can be useful if you want to do something with the exception before passing it up the call chain.
Using throw without any arguments preserves the call stack for debugging purposes.
Your second example will reset the exception's stack trace. The first most accurately preserves the origins of the exception.
Also you've unwrapped the original type which is key in knowing what actually went wrong... If the second is required for functionality - e.g., to add extended information or rewrap with a special type such as a custom 'HandleableException' then just be sure that the InnerException property is set too!
Throw;: Rethrow the original exception and keep the exception type.
Throw new exception();: Rethrow the original exception type and reset the exception stack trace
Throw ex;: Reset the exception stack trace and reset the exception type
If you want you can throw a new Exception, with the original one set as an inner exception.
Most important difference is that the second expression erases the type of the exception. And the exception type plays a vital role in catching exceptions:
public void MyMethod ()
{
// both can throw IOException
try { foo(); } catch { throw; }
try { bar(); } catch(E) {throw new Exception(E.message); }
}
(...)
try {
MyMethod ();
} catch (IOException ex) {
Console.WriteLine ("Error with I/O"); // [1]
} catch (Exception ex) {
Console.WriteLine ("Other error"); // [2]
}
If foo() throws an IOException, the [1] catch block will catch the exception. But when bar() throws IOException, it will be converted to plain Exception and won't be caught by the [1] catch block.
throw or throw ex, both are used to throw or rethrow the exception, when you just simply log the error information and don't want to send any information back to the caller you simply log the error in catch and leave.
But in case you want to send some meaningful information about the exception to the caller you use throw or throw ex. Now the difference between throw and throw ex is that throw preserves the stack trace and other information, but throw ex creates a new exception object and hence the original stack trace is lost.
So when should we use throw and throw e? There are still a few situations in which you might want to rethrow an exception like to reset the call stack information.
For example, if the method is in a library and you want to hide the details of the library from the calling code, you don’t necessarily want the call stack to include information about private methods within the library. In that case, you could catch exceptions in the library’s public methods and then rethrow them so that the call stack begins at those public methods.