Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the exception message property read only?

Tags:

c#

exception

Maybe the most mystifying thing to me in C# is that the Exception class's message property is read-only. Probably because I don't understand the reason for this, I am frustrated when I try to create reasonable exception classes derived from Exception.

For example (and actually what I'm trying to do), I want to create an exception to raise when an attempt to connect to an OPC server. An object of type OPCException is raised if the attempt fails, but I want to give the user more information. So, I have a class named OPCCaException that takes three arguments: the return code from the original exception, the server name, and the host name.

public class OPCCaException : Exception
{
    public OPCCaException(ReturnCode returnCode, string serverName, string nodeName)
    {
        if (nodeName == "")
        {
            this.Message = "Failed to connect to OPC server "+ serverName + 
                           ": " + TranslateReturnCode()";
        }
        else
        {
            this.Message = "Failed to connect to OPC server "+ serverName + 
                           " on node " + nodeName +
                           ": " + TranslateReturnCode()";
        }
    }
}

This seems to me to be a perfectly reasonable thing to do, but it won't compile because the Message property is read-only. The only way to set the message is to pass it to the base class constructor. Why can't I set it in my derived class's constructor? The only way I can think of to do any kind of processing on the arguments is to create a static class to build the message:

public class OPCCaException : Exception
{
    private static string BuildMessage(<some arguments>)
    {
        string message = "some message";
        return message;
    }
    public OPCCaException(ReturnCode returnCode, string serverName, string nodeName) :
        base(BuildMessage(returnCode, serverName, nodeName))
    {
    }
 }

I don't know if that will compile.

What is the standard way to do this?

like image 589
ROBERT RICHARDSON Avatar asked Mar 07 '13 20:03

ROBERT RICHARDSON


People also ask

How do I read an exception message in C#?

C# provides built-in support to handle the exception using try , catch & finally blocks. try block: Any suspected code that may raise exceptions should be put inside a try{ } block. During the execution, if an exception occurs, the flow of the control jumps to the first matching catch block.

Why is InnerException null?

Property Value The InnerException property returns the same value as was passed into the Exception(String, Exception) constructor, or null if the inner exception value was not supplied to the constructor.

What does read-only mean in Javascript?

The readOnly property sets or returns whether a text field is read-only, or not. A read-only field cannot be modified. However, a user can tab to it, highlight it, and copy the text from it. Tip: To prevent the user from interacting with the field, use the disabled property instead.

How do I write an exception message?

In my experience, when it comes to writing exception messages, most developers approach the job with one of these mindsets: Write the shortest possible exception message; if possible, ignore good grammar, punctuation, and proper spelling. Write lovingly crafted error messages for the end users.


4 Answers

public virtual string Message

Message is virtual - so you can easily override it in your class.

public class OPCCaException : Exception
{...
  public override string Message 
  {
    get { return "My fancy text";}
  }
}

Also more standard way of doing it is to pass message via call to base class constructor:

public OPCCaException(...) : base(buildMessage(...))
{
}
like image 121
Alexei Levenkov Avatar answered Sep 26 '22 19:09

Alexei Levenkov


Why is the exception message property read only?

Because exceptions are meant to stay intact as they travel up the stack trace. If, as you capture, you want to provide more information/meaningful message you should wrap the captured exception in another exception. There is a constructor that does exactly that.

This seems to me to be a perfectly reasonable thing to do, but it won't compile because the Message property is read-only.

What you're trying to achieve is perfectly reasonable. The way you're trying to achieve is not. Since Message property is read-only nobody can assign anything to it, including you. For this reason it was made virtual. Read more about overriding it on MSDN.

like image 28
Roman Royter Avatar answered Sep 24 '22 19:09

Roman Royter


You can either pass the message to the base class constructor, or you can override the Message property on your class to return something else. For example:

public class OPCCaException : Exception
{
    ReturnCode returnCode;
    string serverName;
    string nodeName;

    public OPCCaException(ReturnCode returnCode, string serverName, string nodeName)
        : base();
    {
         this.returnCode = returnCode;
         this.serverName = serverName;
         this.nodeName = nodeName;
    }

    public override string Message
    {
        get
        {
             return string.Format("Failed to connect to OPC server {0}{1}: {2}",
                 serverName, 
                 string.IsNullOrEmpty(nodeName ? "" : " on node " + nodeName),
                 TranslateReturnCode(returnCode)
             );
        }
    }
}
like image 32
Brian Rogers Avatar answered Sep 26 '22 19:09

Brian Rogers


Have you noticed that Exception.Message is a virtual property? The appropriate way to handle this would be to override Message and provide your own implementation

public class MyException : Exception
{
    private string myMessage = null;
    public override string Message
    {
        get
        { 
            return String.IsNullOrEmpty(myMessage) ? 
                 base.Message : 
                 myMessage; 
        }
    }

    public MyException(string message) : base()
    {
        myMessage = message;
    }
}
like image 29
psubsee2003 Avatar answered Sep 26 '22 19:09

psubsee2003