Exception with null message - c#

I found that exception message can't be null in C#, and after trying this
var ex = new Exception(null);
Console.WriteLine(ex.Message);
I get the following message:
Exception of type 'System.Exception' was thrown.
But, in this case,
var ex = new Exception(string.Empty);
Console.WriteLine(ex.Message);
the message is just empty.
How this can be explained? Do you think this is expected behavior?

The other answers (not including the answer from chopikadze) seem to be based on a misreading of the facts. Neither example is throwing an exception.
Rather, in the first example, the constructed exception ex is providing a message because the value of the constructor's message parameter was null. The message is "an exception of type 'System.Exception' was thrown".
It's a fairly common practice to have some fallback behavior when an object reference is null, so that's "how it can be explained". Whether it is "expected", of course, depends on your expectations.
Throwing exceptions in the course of handling exceptions can be problematic, so the framework designers must have chosen this behavior to reduce this possibility. It would have been a nightmare, frankly, if we all had to cover the possibility that exception messages might be null.
EDIT
The behavior is also documented in the remarks for the Message property: "If no message was supplied to the constructor for the current instance, the system supplies a default message that is formatted using the current system culture."
I looked in the CLI spec and in the C# spec, and I found no mention of a requirement that Message have a non-null return value, so I guess that supports the view that this behavior is a framework design decision.

Actually constructor doesn't need string, you can absolutely surely use null. This is reflectored part of Exception class:
internal string _message;
public Exception(string message)
{
this.Init();
this._message = message;
}
private void Init()
{
this._message = null;
this._stackTrace = null;
this._dynamicMethods = null;
this.HResult = -2146233088;
this._xcode = -532462766;
this._xptrs = IntPtr.Zero;
this._watsonBuckets = null;
this._ipForWatsonBuckets = UIntPtr.Zero;
this._safeSerializationManager = new SafeSerializationManager();
}
public virtual string Message
{
[SecuritySafeCritical]
get
{
if (this._message != null)
{
return this._message;
}
if (this._className == null)
{
this._className = this.GetClassName();
}
return Environment.GetRuntimeResourceString("Exception_WasThrown", new object[] { this._className });
}
}
So if you use null as message in constructor, localized string like "Exception of type 'System.Exception' was thrown." will be used as Message. It means - there is still your Exception, not another one, but it's property Message returns another (calculated) value instead of null from constructor.
I think that it's defined by design (and maybe is used in another places) that Exception.Message should be always not null. So if we want to allow developers use default constructor for Exception class (for example, for using with reflection or for allowing to populate properties later) but we also want to has Message always not null - we should wrap Message with something. I think, one of the possible place of Message usage is default dialog box showed after exception occurs. This way there could be used just Message property, instead of checking - is Message property equals to null etc.

string.Empty is not null it is a constant for "".
Your first example is giving a default message, your second example is an empty string

Yes, the constructor you are using requires a string. String.Empty is not the same as null therefore it will throw an exception.
http://msdn.microsoft.com/en-us/library/system.exception.aspx

Related

Using reflection, setter throws exception which can't be caught

I am using reflection to set properties on an object. If any of the setters throw an exception, the exception is not caught by the code that makes the SetValue call. Visual Studio tells me that the exception is uncaught by user code.
For example, imagine in the example below that the Title property setter on the object referenced by the "target" variable throws an ArgumentException.
Looking at the call stack, it seems that there is unmanaged code between the snippet below and the setter.
Can somebody please (& thank you!) explain:
Why is this happening in the first place?
Is there a simple way to fix it without re-thinking the program logic?
Here is my code:
try
{
prop.SetValue(target, attr.Value); // target does have a "Title" property
// attr.Value == "Title"
// the setter throws an ArgumentException
}
catch (Exception ex) // No exception is ever caught.
{
errors.Add(ex.Message);
}
Here is the code for one of many properties that I want to set like this:
public string Title
{
get
{
return this.title;
}
set
{
if (string.IsNullOrEmpty(value) || value.Length < 1 || value.Length > 128)
{
throw new ArgumentException("Title must be at least 1 character and cannot be longer than 128 characters.");
}
this.title = value;
}
}
EDIT as stated by #Default, Framework 4.5 does have an overload with only two parameters, so if the user is working with FW 4.5 this answer does not have relevance (at least the last part about PropertyInfo),
You are wrong, it is trapped and here is an example to demonstrate it:
public class ExceptionGenerator
{
public static void Do()
{
ClassToSet clas = new ClassToSet();
Type t = clas.GetType();
PropertyInfo pInfo = t.GetProperty("Title");
try
{
pInfo.SetValue(clas, "test", null);
}
catch (Exception Ex)
{
Debug.Print("Trapped");
}
}
}
class ClassToSet
{
public string Title {
set {
throw new ArgumentException();
}
}
}
What you are doing wrong is obtaining the PropertyInfo, the PropertiInfo's SetValue method expects a third parameter, the index at the property (null in your case), so your "prop" is not a PropertyInfo, I assume it's a FieldInfo, and because that it throws an unhandled exception.
Any exception there should be caught.
See fiddle: https://dotnetfiddle.net/koUv4j
This includes errors in the reflection call itself (setting the property to the wrong Type), or having an exception within the property's setter itself (set throws).
This leads to something else being wrong. Possibilities:
You've got your IDE set to halt on all exceptions
The exception isn't happening where you think it is (like, in the catch, which will rethrow)
If it's not one of those 2 then please provide more information.

Should exceptions contain dynamic data?

I have such method:
public function someMethod($param1 = null, $param2 = null)
{
...
if ($param1 == null &&...)
{
throw new Exception("Some parameter is wrong", 601);
}
}
Is it a good practice to include dynamic data in the Exception msg, since I have the exception code ? For example the exception could look like this:
throw new Exception("First parameter is wrong. You passed: {$param1}", 601);
What is your opinion, is it okey messages to be dynamic or I should stick to fixed text for the Exception messages ?
Should exceptions contain dynamic data?
Should? No. but they can! but be sure that "generating" this dynamic data will not cause another exception.
But you should never throw new Exception(). Extend it for your own custom exceptions or use javas exceptions like IllegalArgumentException

Get name of last called method

I have the following code:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
try
{
this.CheckValue(true); // call method
}
catch(Exception ex)
{
// how to get here name of last called method
}
}
public int CheckValue(bool sender)
{
var qwe = int.Parse("qwe"); // invoke an exception
return 0;
}
}
I need to get in "catch block" name of last called method (in this case "CheckValue"), but it return that called method is "StringToNumber".
I try to get it using StackTrace:
stackTrace.GetFrame(1).GetMethod().Name; -> "Main"
MethodBase.GetCurrentMethod(); -> "Void .ctor()"
ex.TargetSite.Name; -> "StringToNumber"
It's possible to do this?
Short Answer:
Yes, You can!!!
I'd just play around with Extension Methods and the trick here, is to get the last frame of the desired class, otherwise it would get methods of mscorlib assembly. So here it go:
public static string GetLastCalledMethod<T>(this Exception ex)
{
var stackTrace = new System.Diagnostics.StackTrace(ex);
var lastFrame = stackTrace.GetFrames().FirstOrDefault(frame => frame.GetMethod().DeclaringType.FullName == typeof(T).FullName);
string methodName = string.Empty;
if (lastFrame != null)
methodName = lastFrame.GetMethod().Name;
return methodName;
}
Short Answer:
You can't.
Long Answer:
If you really need to do that, you will need to perform logging code in all the methods you want to track.
You can create a global variable (ugh) to store a MethodInfo with the last called method, and inside every method, set it to MethodBase.GetCurrentMethod(). Then whenever you want, you can examine that variable to see which method set it last.
In your case, you probably are trying to determine which method the exception was thrown in. You are looking at TargetSite, which returns the lowest method in the hierarchy, whereas you seem to want the one immediately below the current method. If simply examining Exception.StackTrace doesn't provide enough information, you might be able to parse out information from StackTrace and use reflection to get a MethodInfo. Usually, the StackTrace is good enough.
You may also be able to throw a new exception in the top-level method, so you can get the TargetSite from the new one.
Summary:
If Exception.StackTrace doesn't provide enough information, then you will either have to:
Perform logging code in each method you want to check for.
Parse out what information you can get from the Exception.
Change the exception throwing scheme to throw a new exception with InnerException set to the original exception.
I don't know why you want to do this.. because this is expected behaviour. The site of the exception is what you're being shown.. within the int.Parse() calls.
That being said.. if you really want to do this, you need to wrap a try.. catch in CheckValue, and re-throw the exception from there, but in a way that breaks the call stack.. like so:
public int CheckValue(bool sender) {
try {
var qwe = int.Parse("qwe"); // invoke an exception
return 0;
}
catch (Exception ex) {
throw ex; // this breaks the call stack and re-throws the exception from here..
}
}
Then, ex.TargetSite.Name == "CheckValue". I'm still not sure why you'd want to do this.. as a stack trace will actually show you where it all unwinds from after failure.

uplifitng return value error reporting to Exceptions

In Framework Design guideline book there is a chapter about Exception and they talk about return-value-based error reporting and exception based error reporting and the fact that we in a O.O language like C# we should avoid return-value-based error reporting and use exceptions. With that in mind I was looking at our code that eight years ago was written in Visual Basic and last year with a automatic tool got converted to C#!
So here is a method I am looking at, I was wondering if the advice from that book applies to such a method and if yes, then what would be a better approach for rewriting this method?
public int Update(CaseStep oCaseStepIn)
{
int result = 0;
//Update the master object with the passed in object
result = UCommonIndep.gnUPDATE_FAILED;
if (Validate(oCaseStepIn) == UCommonIndep.gnVALIDATE_FAILED)
{
return result;
}
CaseStep oCaseStep = get_ItemByObjectKey(oCaseStepIn.CopyOfObjectKey);
if (oCaseStep == null)
{
return result;
}
return result;
}
Throw specific exceptions when possible. Then, you don't need a return value in this case.
public void Update(CaseStep oCaseStepIn)
{
//Update the master object with the passed in object
if (Validate(oCaseStepIn) == UCommonIndep.gnVALIDATE_FAILED)
throw new ValidationFailedUpdateException();
CaseStep oCaseStep = get_ItemByObjectKey(oCaseStepIn.CopyOfObjectKey);
if (oCaseStep == null)
throw new KeyObjectNotFoundUpdateException();
if (oCaseStep.Update(oCaseStepIn) != UCommonIndep.gnUPDATE_SUCCESSFUL)
throw new UpdateFailedException();
//*******************************
//FYI - Insert code here to update any Key values that might have changed.
}
UpdateFailedException extends Exception
ValidationFailedUpdateException extends UpdateFailedException
KeyObjectNotFoundUpdateException extends UpdateFailedException
There are (at least) as many opinions on exception handling as there are coders, but a good rule of thumb to start from is that exceptions should be thrown in exceptional circumstances.
So, is an update failure an exceptional occurrence?

Whats the difference between Exception's .ToString() and .Message?

I'm looking through some code and I found e.ToString() and I was wondering if there is a difference to using the ToString() method instead of .Message ?
Reading below, it sounds like it returns more info.
From Microsoft's Docs
ToString
Supported by the .NET Compact Framework.
Overridden. Creates and returns a string representation of the current exception.
Message
Supported by the .NET Compact Framework.
Gets a message that describes the current exception.
If you're looking to get as much information as possible in one go, call ToString():
The default implementation of ToString obtains the name of the class that threw the current exception, the message (my emphasis), the result of calling ToString on the inner exception, and the result of calling Environment.StackTrace. If any of these members is Nothing, its value is not included in the returned string.
It's convenient that you don't have to append all the individual elements together yourself, checking to make sure none are null, etc. It's all built in...
Exception.ToString Method
You can also check out the actual source code at reference.microsoft.com.
Try using .NET Reflector or similar to see what the ToString method on System.Exception is doing:
[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
public override string ToString()
{
return this.ToString(true);
}
private string ToString(bool needFileLineInfo)
{
string className;
string message = this.Message;
if ((message == null) || (message.Length <= 0))
{
className = this.GetClassName();
}
else
{
className = this.GetClassName() + ": " + message;
}
if (this._innerException != null)
{
className = className + " ---> " + this._innerException.ToString(needFileLineInfo) + Environment.NewLine + " " + Environment.GetRuntimeResourceString("Exception_EndOfInnerExceptionStack");
}
string stackTrace = this.GetStackTrace(needFileLineInfo);
if (stackTrace != null)
{
className = className + Environment.NewLine + stackTrace;
}
return className;
}
ToString() returns the Message along with the StackTrace.
ToString() will also recursively include InnerExceptions.
ToString() returns a much longer string which is much more useful than Message when tracking down errors.
You could always just try it and see:
try
{
throw new Exception("This is a test.");
}
catch ( Exception ex )
{
Console.WriteLine(ex);
Console.WriteLine(ex.Message);
}
(You will find that you are correct, .ToString is more informative, including among other things the stack trace.
The ToString methods returns the Message property along with information on where the error occured.
The Message property is intended for a short description of the error, and only contains what the person implementing the Exception put there. The resport from ToString contains additional information that is always included.
If you are running in debug mode, the error report contains more detailed information, e.g. line numbers in the call stack.
The e.ToString() will give you a detailed Message like PrintTrace i think which Display's the Exception Name and the Line where Exception was Thrown where e.Message Output's a Readable Message Only without Specification's.
You can check Exception base constructor

Categories