I have tried this code to raise a manual exception
protected void test ()
try
{
throw new Exception("HI"); //line22
}
catch (Exception ex) { lblerror.Text = ex.ToString(); }
but received exception below
System.ArgumentException: HI at
Project_Test_M_Test.btnsubmit_Click(Object sender, EventArgs e) in
D:\Project\Test\M_Test.aspx.cs:line 22
I want to see error message that I have send not this.
Please use ex.Message instead of ex.ToString().
btw, its not a good idea to throw the base class Exception. please use a more specific one.
This is what you need to do, use Message property to access the error message.
protected void test ()
{
try
{
throw new Exception("HI"); // Exception message passed from constructor
}
catch (Exception ex)
{
lblerror.Text = ex.Message;
}
}
Related
I have an exception occurred when the Database connection failed in a Class. The problem is how do I notify my Main Window that this exception is caught and show a message box to notify my user?
Thanks
Use the Try ... Catch clause like this:
try
{
// The code that could generate an exception
}
catch(Exception ex)
{
MessageBox.Show("Error: " ex.Message);
}
Or if you're using SQL-Server connection, use it like this:
try
{
// The code that could generate an exception
}
catch(SqlException ex)
{
MessageBox.Show("SQL Error: " ex.Message);
}
Thanks. I may have not make my question clearly. I mean this exception
is occurred in one class, but the message box should be show in an
other windows class. So how do I communicate and show this error?
From your clarification in one of the comments:
So if you have class TestClass.cs with method Test in it.
public void Test()
{
//if you want to throw an exception defined by your business logic
if(someCondition == false)
throw CustomException();
//if you have exception in the code
int a = 5;
int b =0;
//here you will be thrown an exception can't divide by 0.
int c = a/b;
}
Your winform Button Click or whatever
public void Button_Click1(object sender, EventArgs e)
{
try
{
TestClass cl = new TestClass();
cl.Test();
}
catch(CustomException custEx)
{
//this for your Bussines logic exception
//write your message
}
catch(DivideByZeroException div)
{
//this for divide by zero exception
//write message
}
//you can catch all other exception like this but I don't advice you to do that
catch(Exception ex)
{
//for this to working properly, this catch should be under all of others(last priority)
}
}
You are apparently able to rethrow an Exception without discarding the stack trace in .NET.
However it doesn't appear to be working.
Basic usage I'm following is thus:
[WebMethod]
public void ExceptionTest()
{
try
{
throw new Exception("An Error Happened");
}
catch (Exception ex)
{
evlWebServiceLog.WriteEntry(ex.ToString(), EventLogEntryType.Error);
throw;
}
}
Problem is, the line number in the exception in the line of the throw; line, not the original throw new line.
I've tested it in a simple exe project and without the logging to the windows log line. It doesn't make any difference, the stack trace always has the wrong line number in it, making it less than useful.
Why is it doing this?
How do I do it correctly?
You do not lose original exception if you place it in an inner exception.
[WebMethod]
public void ExceptionTest()
{
try
{
throw new Exception("An Error Happened");
}
catch (Exception ex)
{
evlWebServiceLog.WriteEntry(ex.ToString(), EventLogEntryType.Error);
throw new Exception("Your message", ex);
}
}
I've used the following for years. Don't know if there a less "dodgy" way to achieve it in more up to date .Net frameworks though:
public void PreserveStackTrace(Exception ex)
{
MethodInfo preserve = ex.GetType().GetMethod("InternalPreserveStackTrace",
BindingFlags.Instance | BindingFlags.NonPublic);
preserve.Invoke(ex,null);
}
To use this:
[WebMethod]
public void ExceptionTest()
{
try
{
throw new Exception("An Error Happened");
}
catch (Exception ex)
{
evlWebServiceLog.WriteEntry(ex.ToString(), EventLogEntryType.Error);
PreserveStackTrace(ex);
throw ex;
}
}
Update: based on #dcastro's comment, I'd fancy an extension method in 4.5 (in < 4.5 it could still be an extension wrapping the method above):
public static void ReThrow(this Exception ex)
{
var exInfo = ExceptionDispatchInfo.Capture(ex);
exInfo.Throw();
}
So you'd just have:
catch (Exception ex)
{
evlWebServiceLog.WriteEntry(ex.ToString(), EventLogEntryType.Error);
ex.ReThrow();
}
The following is my code in C#:
catch(Exception ex)
{
ex.Data.Add("VarName", "object");
throw;
}
Question: doing above, am I going to lose the entry I am adding to Data dictionary? -->as in my opinion, I am rethrowing the exception caught in the catch statement, and it does not have the added Dictionary record from the next line yet.
Should above code instead be:
catch(Exception ex)
{
ex.Data.Add("VarName", "object");
throw ex;
}
but in this case, I don't want to reset the stack trace.
Searched this all over the web and on SO, but no luck.
TIA!
Your initial code should work just fine. You should not lose the dictionary entry.
[EDIT]: Elaboration.
Let's take the following example code:
using System;
class Program
{
static void Main()
{
Change();
Replace();
Inner();
}
static void Change()
{
try {
try {
throw new Exception("This is a message");
} catch (Exception e) {
e.Data.Add("foo", "bar");
throw;
}
} catch (Exception e) {
System.Diagnostics.Trace.WriteLine(e.Message);
System.Diagnostics.Trace.WriteLine(e.Data["foo"]);
}
}
static void Replace()
{
try {
try {
throw new Exception("This is a message");
} catch (Exception e) {
e = new Exception("Different message", e);
e.Data.Add("foo", "bar");
throw;
}
} catch (Exception e) {
System.Diagnostics.Trace.WriteLine(e.Message);
System.Diagnostics.Trace.WriteLine(e.Data["foo"]);
}
}
static void Inner()
{
try {
try {
throw new Exception("This is a message");
} catch (Exception e) {
e.Data.Add("foo1", "bar1");
e = new Exception("Different message", e);
e.Data.Add("foo2", "bar2");
throw e;
}
} catch (Exception e) {
System.Diagnostics.Trace.WriteLine(e.Message);
System.Diagnostics.Trace.WriteLine(e.Data["foo2"]);
System.Diagnostics.Trace.WriteLine(e.InnerException.Message);
System.Diagnostics.Trace.WriteLine(e.InnerException.Data["foo1"]);
}
}
}
When throwing an Exception, what is really thrown is a reference to an Exception object. That reference is what is caught and rethrown. Modifying the underlying object is fine. This is what your initial code does, and what the Change method in my example does.
In the Replace method we modify not the object, but the reference itself. We make it point to a brand new Exception object with a different message and to top it off we also add some data. All this stuff is lost, though, because throw without arguments rethrows the original reference.
Should the need arise to use the second case, you can keep track of your stack trace by including the original exception as InnerException, like I did in the Inner method.
I'm new to ASP.NET and I have a very basic site that I just want to grab all Application Errors and email them to me, while giving the user a error page. I read a lot on the subject and seems to be a lot of information. Below is what I came up with but I'm having problems keeping the Exception in session so I can email it to me.
I keep getting a NullReferenceException was unhandled by user code on the ex.Message from the Error.aspx.cs file.
Any thoughts?
Global.asax.cs-
void Application_Error(object sender, EventArgs e)
{
Exception ex = Server.GetLastError();
HttpContext.Current.Response.Redirect("~/Error.aspx");
}
Error.aspx.cs-
public partial class Error : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Exception ex = (Exception)Session["Exception"];
this.SendEmail(ex);
Session.Remove("Exception");
}
}
private void SendEmail(Exception ex)
{
string body = "An exception occured at "
+ DateTime.Now.ToLongTimeString()
+ " on " + DateTime.Now.ToLongDateString()
+ "<br />" + ex.Message; //ERROR HERE
MailMessage msg = new MailMessage("from#email.com", "to#email.com");
msg.Subject = "Exception in Portal Website";
msg.Body = body;
msg.IsBodyHtml = true;
SmtpClient client = new SmtpClient("localhost");
client.Send(msg);
}
}
Your problem is that you are never setting Session["Exception"], so on your Error.aspx, Exception ex is always going to be null... and then doing ex.Message will throw the NullReferenceException. Even if you fix that and appropriately set Session["Exception"], what you are doing isn't ideal.
You could just send the email from the Application_Error function.
Your Response.Redirect (MSDN Entry) is going to cause ANOTHER exception (ThreadAbortException)
You should look at implementing ELMAH. It is easy to implement and does everything you want to do.
But if all you want to do is fix your code, just move the send email logic to Application_Error and then you don't have to worry about Session.
What I did in a similar instance is to throw all exceptions and then in your global.asax uses the Application_Error method to perform any work you need to with the error message.
void Application_Error(object sender, EventArgs e)
{
// Code that runs when an unhandled error occurs
string exception;
Exception ex = Server.GetLastError();
if (ex.InnerException != null)
{
Exception innerException = ex.InnerException;
exception = ex.InnerException.Message;
}
else
{
exception = ex.Message;
}
//Send email here
//redirect to error page
}
I don't see you pushing the exception object to session, why not move the SendEmail method to global.ascx and SendEmail then redirect user to Error page. There are third party plugins like ELMAH that can do all this easily for you with simple configurations.
I'm in a similar bind. I'm going to check out ELMAH, but my project has a huge restriction on Open Source Projects, yours may to. Sucks to be me!
In which case I'd suggest creating a logging function for the message that you can call directly from the Global.asax. Something like:
void Application_Error(object sender, EventArgs e)
{
Exception ex = Server.GetLastError();
LogException(ex);
HttpContext.Current.Response.Redirect("~/Error.aspx");
}
//Somewhere Else
void LogException(Exception ex)
{
WriteExceptionToEndOfTextFile(ex);
SendEmail();
}
This way if someone decides they want to suppress our exceptions, they can still properly handle the exception.
Here's an interesting question. I have a system that attempts to run some initialization code. If it fails, we call the deinitializer to clean everything up.
Because we call the deinitializer in exception handling, we run the risk that both initialize and deinitialize will fail, and hypothetically, it now seems that we have to throw two exceptions.
It seems pretty unlikely that we will, though. So what happens and what should the code do here?
try { /* init code here */ }
catch (Exception ex)
{
try
{
_DeinitializeEngine();
}
catch (Exception ex2)
{
throw new OCRException("Engine failed to initialize; ALSO failed to deinitialize engine!", ex2);
}
finally
{
throw new OCRException("Engine failed to initialize; failed to initialize license!", ex);
}
}
You shouldn't throw in the Finally block. Instead, use the InnerException to add information in the throw.
Update
What you have to do is to catch and rethrow with the "history" of exception, this is done with InnerException. You can edit it when bulding a new exception. This is a code snippet I just wrote to illustrate the idea that I explain in all the comments below.
static void Main(string[] args)
{
try
{
principalMethod();
}
catch (Exception e)
{
Console.WriteLine("Test : " + e.Message);
}
Console.Read();
}
public static void principalMethod()
{
try
{
throw new Exception("Primary");
}
catch (Exception ex1)
{
try
{
methodThatCanCrash();
}
catch
{
throw new Exception("Cannot deinitialize", ex1);
}
}
}
private static void methodThatCanCrash()
{
throw new NotImplementedException();
}
No need to use double throw with finalize. If you put a break point at the Console.WriteLine(...). You will notice that you have all the exception trace.
If your clean up code is failing and you cannot leave the application in a clean and known state I would let the exception go unhandled (or catch it with the UnhandledException event to log it) then close the application.
Because if you can't handle the first exception, what point is there in catching the second exception?
If I understand your problem correctly, here's what I would have done:
try { /* init code here */ }
catch (Exception ex)
{
// Passing original exception as inner exception
Exception ocrex = new OCRException("Engine failed to initialize", ex);
try
{
_DeinitializeEngine();
}
catch (Exception ex2)
{
// Passing initialization failure as inner exception
ocrex = new OCRException("Failed to deinitialize engine!", ocrex);
}
throw ocrex;
}
You have two possible exception conditions: one in which the first method failed, and one in which both methods failed.
You're already defining your own exception class. So create another (or extend the first) with a RelatedException or PriorException property. When you throw the exception in the second case, save a reference to the first exception in this property.
It's up to the exception handler that catches this exception to figure out what to do with the second exception.