Idov
Idov

Reputation: 5124

Overriding the message of exception in C#

Is there a way to override the message of an exception?
I don't want to make a custom exception but to override the message of an existing exception.
For example: Every time when a ArgumentOutOfRangeException is thrown, I'd like it to contain my message instead of the default one.

Is it possible?

Upvotes: 4

Views: 17063

Answers (3)

The Exception.Message property is declared read-only, so no, you cannot change the Message of a pre-existing Exception object. (The same applies to derived exception types.)

But you can set the message text of an exception you're throw-ing yourself: usually, you pass the message text to the exception constructor:

throw new ArgumentException("Frobbled arguments are not accepted", paramName: …);
//                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

When you define your own exception types, you should follow this protocol; see the section at the end of this answer.

You want to change an existing exception object's Message — Alternatives:

  • Catch the original exception and derive a new exception from it that is identical except for the message:

    …
    catch (ArgumentException ex)
    {
        throw new ArgumentException("New message text", paramName: ex.ParamName);
    }
    

    This is in general not a terribly good idea, because you might lose state data contained in ex (such as its stack trace and InnerException). But it might work just fine in this scenario.

  • Wrap the exception in a new exception so that it becomes the InnerException:

    …
    catch (ArgumentException ex)
    {
        throw new ArgumentException("New message text", innerException: ex);
    }
    

    This is better, because all the original exception's state is preserved. However, in the particular case of ArgumentException it is not obvious at all that the actual exception information is contained in the InnerException.

How to make sure your own exception classes allow setting the message et al.:

When you define a new exception type, it's important for the reasons mentioned above to define constructors that accept a message text and/or an inner exception. So a custom exception class would have at least these constructors:

class MyCustomException : Exception
{
    public MyCustomException() : base() { }
    public MyCustomException(string message) : base(message) { }
    public MyCustomException(string message, Exception innerException) : base(message, innerException) { }
    public MyCustomException(string message) : base(message) { }
}

Upvotes: 3

M. Nasir Javaid
M. Nasir Javaid

Reputation: 5990

You can use try .. . catch

        try
        {
            //Code here regarding array indexing
        }
        catch (ArgumentOutOfRangeException ex)
        {
            throw new ArgumentOutOfRangeException("exception", "New Custom Message");
            //Or show new message
            MessageBox.Show("Your custom Message");
        } 

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1500015

For exceptions you're throwing, you can just pass the message in to the constructor:

throw new ArgumentOutOfRangeException("name", "My custom message");

Note that here, name is the name of the parameter that caused the problem. In C# 6, you should use the nameof operator to make this refactoring-safe:

public void Foo(int x)
{
    if (x > 10)
    {
        throw new ArgumentOutOfRangeException(nameof(x), "That's too big");
    }
}

You can't modify the message of an exception thrown by other code, but you can catch the exception and rethrow another one:

try
{
    ...
}
catch (FooException e)
{
    // Keep the original exception
    throw new BarException("Some message", e);
}

I would try to avoid doing this too much though. If you're considering showing exception messages to users, I would generally shy away from that - they're really aimed at developers. As an example, the ArgumentOutOfRangeException you suggested should generally indicate a bug in your code rather than some external condition (like a network failure or whatever) - the user isn't going to be able to do anything about that bug; it's something you should fix. A network failure or something similar is at least more reasonable for the user to take action about, but frankly it's often not going to be clear what the chain of events is.

Upvotes: 10

Related Questions