如何得到InnerException的细节

时间:2016-10-25 20:42:16

标签: c# exception

  

关于重复。即使我在debuging期间看到Exception对象的一部分,我也可以访问Message属性但不能访问Detail属性。所以问题是为什么无法访问Detail属性。

我遇到了一个例外。

catch (Exception ex)
{
    string msg = ex.InnerException.InnerException.Message;
    // say Exception doesnt have Detail property
    // string detail = ex.InnerException.InnerException.Detail; 
    return Json(new { status = "Fail", message = msg, detail: detail });
}

并不说anthing enter image description here

ex.InnerException 显示相同的消息 enter image description here

ex.InnerException.InnerException。最后是一些真实的消息,"db table duplicated key" enter image description here

ex.InnerException.InnerException.Message 我可以收到消息。 enter image description here

但即使有一个属性"the guilty key"

,也无法获得详细信息Detail

enter image description here

  1. 那么我怎样才能获得详细信息?
  2. 奖励:为什么要深入InnerException两次以获得有意义的消息?

8 个答案:

答案 0 :(得分:3)

我认为现在最优雅的方法是使用C# 6 when keyword in a catch statementC# 7 is operator

try
{
    //your code
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException pex)
{
    string msg = pex.Message;
    string detail = pex.Detail; 
    return Json(new { status = "Fail", message = msg, detail: detail });
}

答案 1 :(得分:2)

  1. 诀窍是识别抛出的异常类型并将General Exception转换为正确的Type,然后您可以访问该Exception类型的扩展属性。
  2. 例如:

    if (processingExcption is System.Data.Entity.Validation.DbEntityValidationException)
    {
        exceptionIsHandled = true;
        var entityEx = (System.Data.Entity.Validation.DbEntityValidationException)processingExcption;
        foreach (var item in entityEx.EntityValidationErrors)
        {
            foreach (var err in item.ValidationErrors)
                returnVal.Invalidate(SystemMessageCategory.Error, err.ErrorMessage);
        }
    }
    else if (processingExcption is System.Data.SqlClient.SqlException && ((System.Data.SqlClient.SqlException)processingExcption).Number == -2)//-2 = Timeout Exception
    {
        exceptionIsHandled = true;
        returnVal.Invalidate(SystemMessageCategory.Error, "Database failed to respond in the allotted time. Please retry your action or contact your system administrator for assistance.", 
            messageCode: Architecture.SystemMessage.SystemMessageCode.DBTimeout);
    }
    
    1. 您正在寻找的详细信息是2个内部异常,这是偶然的。根据捕获和包装异常的次数将决定您关心的异常有多深 - 最好的办法是遍历异常堆栈,查找您希望处理的异常类型。

答案 2 :(得分:1)

参考你自己的答案我评论说,你肯定应该更加防守,否则你可能会在你的catch子句中冒一个空引用异常。

catch (Exception ex)
{
    string Detail = string.Empty;

    while ( ex != null ) 
    {
        if ( ex is Npgsql.NpgsqlException )
        {
            // safe check
            Npgsql.NpgsqlException ex_npg = (Npgsql.NpgsqlException)ex;
            Details = ex_npg.Detail;
        }
        // loop
        ex = ex.InnerException;
    }

    // warning, Detail could possibly still be empty!
    return Json(new { status = "Fail", detail = Detail });
}

答案 3 :(得分:0)

  1. 您无法获得超过此例外情况的详细信息
  2. 在innerexceptions上显示真正的异常循环,直到它为null。然后你到达了第一个

    1. 从源类或函数抛出异常,然后由上层类重新引发,因为源上没有错误处理,所以它会抛出更多全局细节

答案 4 :(得分:0)

嗯,这很难过,但内在的例外不是魔术棒。通常,它只是一个对象,您调用的代码的作者将其作为Exception构造函数的第二个参数。所以,一般的回答是:“没办法”。但调试器有时可以帮助:)。我会说 - 调用异常堆栈通常更具描述性的InnerException。

答案 5 :(得分:0)

快速解决方案是单击“快速监视”窗口中的“详细信息”属性。您的答案将位于快速监视窗口顶部的“Expression”文本框中。例如,Postgres重复详细信息的表达式为:

$('#LocalClip').on('change', function() {
    var file = $(this)[0].files[0];
    var url = URL.createObjectURL(file);
    $('video').attr('src', url);
});

答案 6 :(得分:0)

这是我的功能,可从Postgres异常中获取更多信息

catch (Exception ex)   {
                // Get PGSQL exception info              
                var msg = ExceptionMessage (ex);
}

public static string            ExceptionMessage            (Exception ex) {
            string msg = ex.Message;

            var pgEx = ex as PostgresException;
            if (pgEx != null) { 
                msg = pgEx.Message;
                msg += pgEx.Detail != null ? "\n"+pgEx.Detail.ToStr() : "";
                msg += pgEx.InternalQuery != null ? "\n"+pgEx.InternalQuery.ToStr() : "";
                msg += pgEx.Where != null ? "\n"+ pgEx.Where : "";
            }

            return msg;
        }

答案 7 :(得分:0)

谢谢麦西 这个解决方案非常适合拦截 PostgreSQL 错误

我对此只做了更正

msg += pgEx.Detail != null ? "\n"+pgEx.Detail.ToStr() : "";
msg += pgEx.InternalQuery != null ? "\n"+pgEx.InternalQuery.ToStr() : "";

代替

msg += pgEx.Detail != null ? "\n" + pgEx.Detail.ToString() : "";
msg += pgEx.InternalQuery != null ? "\n" + pgEx.InternalQuery.ToString() : "";