This is the code:
var serializer = new DataContractSerializer(typeof(QuoteAndOfferCollection));
try
{
using (var file = File.OpenRead(filename))
{
offers = (QuoteAndOfferCollection)serializer.ReadObject(file);
}
}
catch (SerializationException sex)
{
File.AppendAllText(log, "Deserialization failed - " + sex);
return;
}
And this is the error I get:
xmlDeserialization failed - System.Runtime.Serialization.SerializationException: There was an error deserializing the object of type Services.Dto2.QuoteAndOfferCollection. The value '' cannot be parsed as the type 'Int32'. ---> System.Xml.XmlException: The value '' cannot be parsed as the type 'Int32'. ---> System.FormatException: Input string was not in a correct format.
at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
at System.Xml.XmlConvert.ToInt32(String s)
at System.Xml.XmlConverter.ToInt32(String value)
I am not able to trace the '' part.
Catch the exception and get the value of file.Position. That will give you some idea of where in the file the offending line is. You can do better than that if you wrap a custom stream around the FileStream and keep track of the number of lines read.
You might also be able to create an XmlReader, and pass that to ReadObject. When you catch the exception, examine the reader's properties. It might tell you exactly what line had the error.
But you'll need move where the exception is caught. That is, rather than:
try
{
using (stream)
{
// deserialize
}
}
catch
{
}
you want to write:
using (stream)
{
try
{
// deserialize
}
catch
{
}
}
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
I am getting a weird error on run that I can't figure out. When I am in Visual Studio no error is thrown until I run the program. When I run it however I get an error saying that there was an unhandled exception on type. This is pertaining to the conversion of the field[0] to an int, any advice?
empReader = new StreamReader(fileName);
while (empReader.Peek() > -1)
{
string line = empReader.ReadLine(); //read a line from the text file
string[] fields = line.Split(',');
int idCheck = Convert.ToInt32(fields[0]);
empTempId.Add(idCheck);
}
empReader.Close();
If you're unsure whether or not the value will be an integer, use int.TryParse instead:
int idCheck;
if (int.TryParse(fields[0], out idCheck))
empTempId.Add(idCheck);
This prevents a runtime exception by trying to convert, then returning false if it cannot do so.
You can wrap it in a try/catch block.
try {
int idCheck = Convert.ToInt32(fields[0]);
Console.WriteLine("{0} --> {1}", fields[0], idCheck);
}
catch (FormatException) {
Console.WriteLine("{0}: Bad Format", fields[0]);
}
catch (OverflowException) {
Console.WriteLine("{0}: Overflow", fields[0]);
}
This comes from a book but won't debug with correct message in my Visual Studio 2010, it just gives me Unhandled exception at throw new ApplicationException("Smth. bad happened", e);
Is there an error in the book or is it my VS2010 exception settings maybe? The console output is supposed to show that given the file does not exist the inner and outer trace will be printed along with File Not Found. Does it have to do with Just-in-time debugging?
Current Output:Unhandled Exception.........................................................
Desired output:http://www.introprogramming.info/wp-content/uploads/2013/07/clip_image008.png
class program
{
static void Main()
{
try
{
string fileName = "WrongFileName.txt";
ReadFile(fileName);
}
catch (Exception e)
{
throw new ApplicationException("Smth. bad happened", e);
}
}
static void ReadFile(string fileName)
{
TextReader reader = new StreamReader(fileName);
string line = reader.ReadLine();
Console.WriteLine(line);
reader.Close();
}
}
If you want to wrap an exception in your own and have it bubble up, you should remove the inner try, since every try needs a matching catch. Since you're wrapping an exception of your own with the original exception, it doesn't serve any purpose if you are immediately catching it.
try
{
string fileName = "WrongFileName.txt";
ReadFile(fileName);
}
catch (Exception e)
{
throw new ApplicationException("Smth. bad happened", e);
}
EDIT:
This is expected behavior. You're explicitly throwing an exception, and no one is handling it. The book is likely trying to make the point that you can wrap exceptions to provide additional information, while still preserving the original exception. Check to ensure that the file you're trying to open is in the right place.
As an additional note, you should really wrap the file stream in a using block to ensure that the underlying handles/resources are closed.
static void ReadFile(string fileName)
{
using (TextReader reader = new StreamReader(fileName))
{
string line = reader.ReadLine();
Console.WriteLine(line);
reader.Close();
}
}
You have to make sure that you the file "WrongFileName.txt" is in your project's Bin/Debug folder (you include the file in the project and set it's build action to Content and Copy always, if you want it not to throw the exception.
I presume that the book was trying to show, that when the file name is correct, the program will go through normally, but otherwise will cause error.
The catch block gets run because the file doesn't exist in this case and therefore the action inside is executed. This concrete action is to throw the exception again but with more helpful information. You can also see, that this new exception's constructor accepts the original exception as the second parameter, which means it will be included in this exception's InnerException property.
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
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.