如何在 c# 中编写自定义异常时使用内部异常

本文关键字:内部 异常 自定义异常 | 更新日期: 2023-09-27 18:25:50

我正在编写自定义异常类,并在需要时使用它们登录到elmah。

public class MyCustomLogException : Exception
{
    public string Property1 { get; protected set; }
    public string Property2 { get; protected set; }
    public string Property3 { get; protected set; }
    internal MyCustomLogException(string property1, string property2, string property3)
    {
        Property1 = property1;
        Property2 = property2;
        Property3 = property3;        
    }
    public override string Message
    {
        get
        {
            return string.Format("Error logging to db using Property1 = {0}, Property2 = {1} and Property3 = {2}", Property1, Property2, Property3);
        }
    }
}

我正在使用

public int LogSomethingToDb(SomeModel log)
{
    try
    {
        // log to db
    }
    catch(Exception exception)
    {
        // to do how to use this exception ?
        throw new MyCustomLogException(log.Property1, log.Property2, log.Property3);
    }
}

如何使用上述异常消息、堆栈跟踪等,以便我最终不会吃掉"异常"消息。

我希望也记录异常的确切详细信息,例如,如果它是实体框架异常或空引用异常等,只需阅读 elmah 日志即可。

更新

是的,当然早些时候使用我的代码,我得到了 MyCustomLogException 作为异常记录和"使用 Property1 = {0}、Property2 = {1} 和 Property3 = {2} 将错误记录到数据库"的消息作为异常消息。这样,只需阅读日志,我就可以找出问题所在,然后可以读取内部异常以获取更多详细信息。– 亚西尔 8分钟前

现在使用新代码,在我的情况下,实际的异常类 Sql 正在被记录下来,并且异常消息为"违反 UNIQUE KEY 约束'IX_abc_log'。无法在对象"dbo.abc"中插入重复的键。语句已终止",并且我的自定义异常类和消息记录为内部异常

如何在 c# 中编写自定义异常时使用内部异常

编写自定义异常时,自定义异常至少应如下所示:

[Serializable]
public class CustomException : Exception
{
    public CustomException()
        : base() { }
    public CustomException(string message)
        : base(message) { }
    public CustomException(string format, params object[] args)
        : base(string.Format(format, args)) { }
    public CustomException(string message, Exception innerException)
        : base(message, innerException) { }
    public CustomException(string format, Exception innerException, params object[] args)
        : base(string.Format(format, args), innerException) { }
    protected CustomException(SerializationInfo info, StreamingContext context)
        : base(info, context) { }
}

您将看到,现在异常可以在其构造函数中获取内部异常,这就是您正在寻找的。

当您想要添加属性时,可以再添加一个构造函数,如下所示:

    public CustomException(string message, Exception innerException, string property1, string property2)
        : base(message, innerException) { 
    // Do whatever you want with the extra properties here.    
}

编辑 提问者希望看到自定义异常消息,因此自定义异常被修改为:

[Serializable]
public class CustomException : Exception
{
    public CustomException()
        : base() { }
    public CustomException(string message)
        : base(message) { }
    public CustomException(string format, params object[] args)
        : base(string.Format(format, args)) { }
    public CustomException(string message, Exception innerException)
        : base(message, innerException) { }
    public CustomException(string format, Exception innerException, params object[] args)
        : base(string.Format(format, args), innerException) { }
    protected CustomException(SerializationInfo info, StreamingContext context)
        : base(info, context) { }
    // Added a custom constructor to allow adding the custom properties:
    internal CustomException(string message, Exception innerException, string property1, string property2, string property3) 
        : base(message, innerException) { }
    {
        Property1 = property1;
        Property2 = property2;
        Property3 = property3;        
    }
    // 3 properties holding all the values of the properties passed to it.
    public string Property1 { get; protected set; }
    public string Property2 { get; protected set; }
    public string Property3 { get; protected set; }
    // Override the message to allow custom exception message to be passed to Elmah.
    public override string Message
    {
        get
        {
            return string.Format("Error logging to db using Property1 = {0}, Property2 = {1} and     Property3 = {2}", Property1, Property2, Property3);
        }
    }
}