Rodders
Rodders

Reputation: 2435

How can I get the internal "message" value of a System.Exception?

I have an FTP exception thrown from a third-party assembly which is quite generic:

Exception of type 'JSchToCSharp.SharpSsh.jsch.SftpException' was thrown.

On inspection of the Exception, I see there is a private/internal member called message (lower-case m) that contains my error message:

FTP Exception

How can I get the value of this message member?

I have tried to use reflection to get it but null is returned from GetValue:

    BindingFlags bindFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
        | BindingFlags.Static;
    FieldInfo field = type.GetField(fieldName, bindFlags);
    var value = field.GetValue(instance);

    return value.ToString();

It doesn't appear to be Non-Public or Static so I'm a little unsure as to what to use as my BindingFlags.

Thanks

Upvotes: 1

Views: 220

Answers (2)

Yuval Itzchakov
Yuval Itzchakov

Reputation: 149646

The problem seems to be that you're printing out SftpException.Message instead of SftpException.message (notice the lowercase m).

The author of the library thought (for an unknown reason) that it is a good idea to expose a public field called message instead with the same name as a property called Message, which is from the Exception base class, but contains different content.

This example:

void Main()
{
    try
    {
        throw new SftpException(1, "hello");
    }
    catch (SftpException e)
    {
        Console.WriteLine(e.message);
    }
}

Yields "hello".

Note you can also use the ToString on the custom SftpException for it to print the actual error message. This would also work:

Console.WriteLine(e.ToString());

Side note:

I used ILSpy to look at the SftpException class to see the access modifier of the message field. It looks like this:

ILSpy image of SftpException class

Upvotes: 2

balexandre
balexandre

Reputation: 75133

from your breakpoint you could see that the Exception is not a general exception, it has a known type, so you could actually catch that Exception type as:

try {
    ... 
} 
catch(JSchToCSharp.SharpSsh.jsch.SftpException ex1) {
   // I'm sure that ex1.Message will have what you need
}
catch(Exception ex2)
{
  // for any other Exception types...
}

Upvotes: 1

Related Questions