1

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

9
  • @SonerGönül that will return Exception of type ... as specified in the breakpoint Commented Oct 28, 2015 at 9:24
  • Which SSH library is this? Commented Oct 28, 2015 at 9:25
  • @Yuval Itzchakov it's JSchToCSharp.SharpSSH Commented Oct 28, 2015 at 9:26
  • Is it open source? Where did you take it from? Commented Oct 28, 2015 at 9:32
  • 2
    This library is pretty borken, it completely fails to initialize its Exception base class. Fixing it is best. The message member is otherwise a public field, using the default binding flags is good enough. Or just plain catching the SftpException so you don't have to use reflection. Commented Oct 28, 2015 at 9:37

2 Answers 2

2

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

Sign up to request clarification or add additional context in comments.

3 Comments

@Suited, why do you think message is private/internal member? @Yuval, bad library costs too much time.
@qxg I think he assumed it was private because the debugger represents it as a field, and usually, fields aren't public.
I for some unknown (silly) reason was catching a JSchException even though it's there in black and white as a SftpException! The message field obviously wasn't present in JSchException so assumed it must be private. This works great Yuval! And as does Balexandres answer if I catch the correct exception!!
1

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... } 

5 Comments

I'm not sure. What if SftpException didn't call base(message)?
you need to see the code, but I'm almost sure that SftpException inherits from Exception to behave like that, that will suffice...
I'd tried this already but just tried again and unfortunately, ex1.Message gives me the same "Exception of type 'JSchToCSharp.SharpSsh.jsch.SftpException' was thrown."
SftpException should be like this: public SftpException(string message) : base("Exception is thrown at here.") { this.message = message; }. Message property will not help here.
Thank you sir. I was being an idiot and catching the wrong exception type. This does indeed work.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.