I am serializing a XML File.During the serialization ,I am receiving general exception.It is hard trace the problem.
my code is:
try
{
string m_fileName = #"d:\Xml\Person.xml";
XmlSerializer xmlPerSerlzr = new XmlSerializer(typeof(person));
txtWrt = new StreamWriter(m_fileName);
xmlPerSerlzr.Serialize(txtWrt, person);
}
catch(Exception serExp)
{
MessageBox.Show("Exception is :" + serExp.Message.ToString());
}
Error Message :
There was an error reflecting type "Person"
My question is how can i force the CLR to emit the exact error ?
Check the type of the exception, e.g.
serExp.GetType().ToString()
and check for an inner exception (both type and message).
That should give you some more useful info.
Use:
exc.ToString();
In Debug mode in Exception DialogBox, select View details option.
Probably You don't implement 0-parameter constructor.
I think it is better to check also the stack trace and the inner exception.
You can use something like that
string GetExceptionString(Exception ex)
{
string str = "";
while (ex != null)
{
str += ex.Message + "\n" + ex.StackTrace;
ex = ex.InnerException;
}
return str;
}
Use
serExp.StackTrace
instead of
serExp.Message.ToString()
Set a breakpoint in the catch clause, then run in debug mode. You can then explore the exception object easier and figure out what is going on.
Related
try
{
//This code BlockLine no 1Line no 2Line no 3etc
}
catch (Exception ex)
{
LblError.Text= ex.Message + ex.InnerException.Message
}
I have a code with a try catch block. The try block has more than one line of code. I would like to know which line present within the try block is raising the exception.
You will need to look at the Stack Trace of the exception to track the line that throws the exception.
however if you want to get the full details about the exception use ToString method
( using System.Diagnostics; )
int lineNumber = (new StackTrace(ex, true)).GetFrame(0).GetFileLineNumber();
var fileName = (new StackTrace(ex, true)).GetFrame(0).GetFileName();
Should give you where the problem started.
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
I want a better way to catch database error details.
I'm currently using :
try
{
dbconn.table.AddObject(newRow);
dbconn.SaveChanges();
}
catch (Exception ex)
{
Console.WriteLine("DB fail ID:" + Row.id);
}
many times I found the Exception ex can no give me details on how the exception happen.
I think these exception most likely to be the DB connection kind.
So is there a better way to catch this ?
You should also output the exception. Most of the time, it holds useful and detailed information (e.g. names of violated constraints). Try this:
try
{
dbconn.table.AddObject(newRow);
dbconn.SaveChanges();
}
catch (Exception ex)
{
Console.WriteLine("DB fail ID:" + Row.id);
Console.WriteLine(ex.ToString());
}
For full details, use the ToString() method, it will give you the stack trace as well, not only the error message.
Use Console.WriteLine(ex.GetType().FullName) (or put a breakpoint and run under a debugger) to see the actual exception type being thrown. Then visit MSDN to see its description and base classes. You need to decide which of the base classes provides you with the information needed by exposing such properties. Then use that class in your catch() expression.
For Entity Framework, you might end up with using EntityException and then checking the InnerException property for the SQL exception object that it wraps.
try
{
dbconn.table.AddObject(newRow);
dbconn.SaveChanges();
}
catch (EntityException ex)
{
Console.WriteLine("DB fail ID:" + Row.id + "; Error: " + ex.Message);
var sqlExc = ex.InnerException as SqlException;
if (sqlExc != null)
Console.WriteLine("SQL error code: " + sqlExc.Number);
}
Instead of Exception use SqlException.
SqlException give you more detail. it has a Number property that indicate type of error and you can use that Number in a switch case to give some related information to user.
In short, yes there is a better way to handle it. The 'how' of it is up to you.
Exception handling in C# goes from the most specific exception type to the least specific. Also, you aren't limited to using just one catch block. You can have many of them.
As an example:
try
{
// Perform some actions here.
}
catch (Exception exc) // This is the most generic exception type.
{
// Handle your exception here.
}
The above code is what you already have. To show an example of what you may want:
try
{
// Perform some actions here.
}
catch (SqlException sqlExc) // This is a more specific exception type.
{
// Handle your exception here.
}
catch (Exception exc) // This is the most generic exception type.
{
// Handle your exception here.
}
In Visual Studio, it is possible to see a list of (most) exceptions by pressing CTRL+ALT+E.
I want a central place to extract information from an exception, set all the information I need to its message parameter and then rethrow that information as an Exception of the same type.
The better solution probably would be to do this at the place where the exception is finally being handled (and its message logged), but.. I have control over the place throwing the exception, and not over the place that receives the exception and only logs its Message content.
Apart from that design decision and given that message is a readonly property, I would have (?) to create a new Exception object in some way, is there a way to make the new exception object the same type as the original one?
Here is my code, which does not compile - it stumbles over the throw line (where I try to dynamically cast the object).
public static void RethrowExceptionWithFullDetailInMessage(string msg, Exception ex)
{
Exception curEx = ex;
int cnt = 0;
while (curEx != null)
{
msg += "\r\n";
msg += cnt++ + " ex.message: " + curEx.Message + "\r\n";
msg += "Stack: " + curEx.StackTrace;
curEx = curEx.InnerException;
}
object newEx = Convert.ChangeType(new Exception(msg), ex.GetType());
throw (ex.GetType())newEx;
}
Does this
throw (Exception)newEx;
preserve the type? (It compiles.)
Does the Convert.ChangeType make sure I get an Exception of the correct type?
What you are trying to do here is not as easy as it seems and there are lots of pitfalls to consider.
Remember, that Convert.ChangeType() will convert one type to another (assuming such a path exists, like converting a string to an int for example). Most exceptions wont do this (Why would they?)
IN order to pull this off, you would have to examine the exception type at runtime with the GetType() method and locate a constructor that has requirements you can satisfy and invoke it. Be careful here, since you don't have control over how all exceptions are defined there is no guarantee you will have access to "standard" constructors.
That being said, if you feel like being a rule breaker you could do something like this...
void Main()
{
try
{
throw new Exception("Bar");
}
catch(Exception ex)
{
//I spit on the rules and change the message anyway
ex.GetType().GetField("_message", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(ex, "Foo");
throw ex;
}
}
You could do this to dynamically call the constructor of the exception type:
object newEx = Activator.CreateInstance(ex.GetType(), new object[] { msg });
Your original code would fail at runtime, because for Convert.ChangeType towork, the exception type would have to implement IConvertible and support conversion to the other exception type, which i doubt.
May be it's a bit late, but would this work for you?
catch (Exception ex)
{
throw new Exception("New message", ex);
}
You can change the exception message via reflection like this...
Exception exception = new Exception("Some message.");
var type = typeof(Exception);
var flags = BindingFlags.Instance | BindingFlags.NonPublic;
var fieldInfo = type.GetField("_message", flags);
fieldInfo.SetValue(exception, message);
So you can create an extension method...
namespace ExceptionExample
{
public static class ExceptionExtensions
{
public static void SetMessage(this Exception exception, string message)
{
if (exception == null)
throw new ArgumentNullException(nameof(exception));
var type = typeof(Exception);
var flags = BindingFlags.Instance | BindingFlags.NonPublic;
var fieldInfo = type.GetField("_message", flags);
fieldInfo.SetValue(exception, message);
}
}
}
And then use it...
...
using static ExceptionExample.ExceptionExtensions;
public class SomeClass
{
public void SomeMethod()
{
var reader = AnotherClass.GetReader();
try
{
reader.Read();
}
catch (Exception ex)
{
var connection = reader?.Connection;
ex.SetMessage($"The exception message was replaced.\n\nOriginal message: {ex.Message}\n\nDatabase: {connection?.Database}");
throw; // you will not lose the stack trace
}
}
}
You have to keep in mind that if you use "throw ex;" the stack trace will be lost.
To avoid this you must use "throw;" without the exception.
Supplemental comment.
These all work in supplementing the exception message, but I found that using "throw" did NOT preserve the StackTrace - the last trace pointed to the actual "throw" statement (dropping the root cause location).
From discussions elsewhere, it's clear there are some circumstances that throw doesn't preserve due to CLR stack limitations
Throw and preserve stack trace not as expected as described by Code Analysis
Solution: dump the StackTrace in each exception (e.g. and add to the error message) and/or dump to logging
Hello I would like to write my userdefined exception to a log file.
So Instead of throwing my exception I would like to log that message into a txt file.
The constructor for my exception looks like this:
public OpenFileException(string pathToOpen, Exception innerexception)
: base("Couldn't find the path: " + pathToOpen, innerexception)
{
this.pathToOpen = pathToOpen;
}
This is how I am logging my exception at the moment:
try
{
string data = Read(txtLocation.Text);
txtInfo.Text = data;
}
catch (Exception ex)
{
WriteLog("[" + DateTime.Now + "]" + " " + ex.Message);
MessageBox.Show(" ");
throw new OpenFileException(txtLocation.Text, ex);
}
So what I'm asking is. How can I log my string "Couldn't find the path: " to a txt file?
I would normally catch and log the user defined exception outside the normal try/catch
try {
try {
string data = Read(txtLocation.Text);
txtInfo.Text = data;
} catch (Exception ex) {
throw new OpenFileException(txtLocation.Text, ex);
}
....
} catch(OpenFileException ex) {
WriteLog("[" + DateTime.Now + "]" + " " + ex.Message);
MessageBox.Show(" ");
} catch(Exception ex) {
WriteLog("[" + DateTime.Now + "]" + " " + ex.Message);
MessageBox.Show(" ");
}
You are creating a user defined exception so you can handle it differently
It looks a bit overkilling, why don't you use Log4Net and let it write files or send you emails depending on its configuration in the app.config?
basically you get all what you can want out of the box with no effort, then you can concentrate on what matters the most.
even if you decide to keep your current logic, I would anyway create a Logger class which does everything instead of having to specify DateTime.Now and other magic in every single catch block of your application.
You can use, instead of reinvent the wheel, log4net http://logging.apache.org/log4net/ or NLog http://nlog-project.org/wiki/Documentation both worth the effort to learn and use even in simple applications.
You need to find a way to get your exception thrown when a file is not found.
I don't think this is a good idea, because .NET already throws the FileNotFoundException when a file is not found. You should catch that and log the message that way.
try
{
string data = Read(txtLocation.Text);
txtInfo.Text = data;
}
catch (FileNotFoundException ex)
{
string log = String.Format("[{0}] Couldn't find the path: {1}"
, DateTime.Now
, ex.FileName);
WriteLog(log);
}
Don't make a new exception type when one already exists.
(Forgive the idiosyncrasies in my formatting)
From Framework Desing Guidelines:
Do override ToString when your exception provides extra properties.
Then you can just call log.Error(exception) and it will be logged just the way you wrote ToString() without extra actions.