【问题标题】:How can I get the internal "message" value of a System.Exception?如何获取 System.Exception 的内部“消息”值?
【发布时间】:2015-10-28 18:42:46
【问题描述】:

我有一个从第三方程序集抛出的 FTP 异常,这是非常通用的:

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

在检查异常时,我看到有一个名为 message(小写 m)的私有/内部成员包含我的错误消息:

我怎样才能得到这个message成员的价值?

我尝试使用反射来获取它,但是从 GetValue 返回 null:

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

    return value.ToString();

它似乎不是 Non-PublicStatic,所以我有点不确定将什么用作我的 BindingFlags.

谢谢

【问题讨论】:

  • @SonerGönül 将返回断点中指定的 Exception of type ...
  • 这是哪个 SSH 库?
  • @Yuval Itzchakov 这是 JSchToCSharp.SharpSSH
  • 它是开源的吗?你是从哪里弄来的?
  • 这个库很糟糕,它完全无法初始化它的异常基类。修复它是最好的。 message 成员否则是一个公共字段,使用默认绑定标志就足够了。或者只是简单地捕获 SftpException,这样您就不必使用反射。

标签: c# exception reflection


【解决方案1】:

问题似乎是您打印出SftpException.Message 而不是SftpException.message(注意小写m)。

库的作者认为(出于未知原因)公开一个名为 message 的公共 字段 而不是与名为 Message 的属性同名是个好主意,它来自Exception 基类,但包含不同的内容。

这个例子:

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

产生“你好”。

请注意,您还可以使用自定义 SftpException 上的 ToString 来打印实际的错误消息。这也可以:

Console.WriteLine(e.ToString());

旁注:

我使用 ILSpy 查看 SftpException 类以查看 message 字段的访问修饰符。它看起来像这样:

【讨论】:

  • @Suited,你为什么认为message 是私人/内部成员? @Yuval,糟糕的图书馆花费太多时间。
  • @qxg 我认为他假定它是私有的,因为调试器将它表示为一个字段,并且通常,字段不是公共的。
  • 由于某种未知(愚蠢)的原因,我捕获了一个 JSchException,即使它作为 SftpException 以黑白形式存在! message 字段显然不存在于 JSchException 中,因此假定它必须是私有的。这对尤瓦尔很有效!如果我发现正确的异常,Balexandres 也会回答!
【解决方案2】:

从您的断点您可以看到 Exception 不是一般异常,它具有已知类型,因此您实际上可以将该异常类型捕获为:

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

【讨论】:

  • 我不确定。如果SftpException 没有调用base(message) 怎么办?
  • 您需要查看代码,但我几乎可以肯定 SftpException 继承自 Exception 的行为,这就足够了......
  • 我已经尝试过了,但只是再次尝试,不幸的是,ex1.Message 给了我同样的“抛出了 'JSchToCSharp.SharpSsh.jsch.SftpException' 类型的异常。”
  • SftpException 应该是这样的:public SftpException(string message) : base("Exception is thrown at here.") { this.message = message; }。消息属性在这里没有帮助。
  • 谢谢先生。我是个白痴,发现了错误的异常类型。这确实有效。
猜你喜欢
  • 1970-01-01
  • 2015-06-03
  • 2013-05-05
  • 1970-01-01
  • 2021-09-08
  • 2014-10-25
  • 2020-09-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多