什么是内部异常

时间:2014-04-03 01:14:40

标签: .net exception-handling inner-exception

我已阅读过MSDN,但我无法理解这个概念。

如果我错了,请纠正我,

  

对于当前异常,将使用innerexception。

首先发生内部异常,然后发生当前异常(如果有异常),这就是为InnerException检查null的原因。为了保留内部异常,我们必须将其作为参数传递。

我是对的吗?

3 个答案:

答案 0 :(得分:24)

您可以看到以下代码。

第一步,我将“abc”解析为整数。它会引发FormatException。

在catch块中,我尝试打开文本文件以记录异常消息。但是这个文件不存在。将引发FileNotFoundException。

我想知道是什么引发了第二个异常,所以我将第一个异常(或FormatException)添加到第二个异常的构造函数中。

现在第一个异常是InnerException的第二个异常。

在catch块中,我可以访问InnerException属性以了解第一个异常是什么。

它有用吗?

using System;
using System.IO;
public class Program
{
    public static void Main( )
    {
        try
        {
            try
            {
                var num = int.Parse("abc");                
            }
            catch ( Exception inner )
            {
                try
                {
                    var openLog = File.Open("DoesNotExist", FileMode.Open);
                }
                catch
                {
                    throw new FileNotFoundException("OutterException", inner);
                }                              
            }
        }
        catch ( Exception e)
        {
            string inMes, outMes;
            if (e.InnerException != null)
                inMes = e.InnerException.Message;
            outMes = e.Message;
        }        
    }
}

答案 1 :(得分:14)

内部异常是导致当前异常的异常。

如果您希望显示与您的代码捕获的异常不同的异常,但您不想丢弃原始上下文,则会使用它。

为了让新的异常有关于前一个的信息,就像你说的那样,你将它作为构造函数参数传递给新的。

通常,null内部异常意味着当前异常是异常情况的根本原因。

答案 2 :(得分:1)

异常对象只有在到达catch块时才会被读取,有时您的代码无法处理异常,但它可以通过创建新的异常和包装来添加更多信息里面最初抛出的异常。这使得您可以添加信息,但不需要逐个字段地复制原始异常中的每条信息(如果您不知道将抛出的异常类型,甚至可能不可能)。

这是我的一个项目的一个略微修改的片段,它使用了一些处理异常的东西。

    private void SomeFunction(string username, string password)
    {
        try
        {
            try
            {
                _someObject.DoSpecialPrivilegedFunction(username, password);
            }
            catch (UnauthorizedAccessException ex)
            {
                throw new UserUnauthorizedException(username, "DoSpecialPrivilegedFunction", ex);
            }
            catch (IOException ex)
            {
                throw new UserModuleActionException("A network IO error happend.", username, "DoSpecialPrivilegedFunction", ex);
            }

            //Other modules

        }
        catch (Exception ex)
        {
            //If it is one of our custom expections, just re-throw the exception.
            if (ex is UserActionException)
                throw;
            else
                throw new UserActionException("A unknown error due to a user action happened.", username, ex);
        }
    }

//elsewhere
[Serializable]
public class UserUnauthorizedException : UserModuleActionException
{
    private const string DefaultMessage = "The user attempted to use a non authorized module";

    public UserUnauthorizedException()
        : base(DefaultMessage)
    {
    }

    public UserUnauthorizedException(string message) 
        : base(message)
    {
    }

    public UserUnauthorizedException(string message, Exception innerException) 
        : base(message, innerException)
    {
    }

    public UserUnauthorizedException(string username, string module, Exception innerException = null) : base(DefaultMessage, username, module, innerException)
    {
    }

    protected UserUnauthorizedException(SerializationInfo info, StreamingContext context) 
        : base(info, context)
    {
    }
}

[Serializable]
public class UserModuleActionException : UserActionException
{
    private readonly string _module;

    public UserModuleActionException()
    {
    }

    public UserModuleActionException(string message) : base(message)
    {
    }

    public UserModuleActionException(string message, Exception innerException) : base(message, innerException)
    {
    }

    public UserModuleActionException(string message, string username, string module, Exception innerException = null)
        : base(message, username, innerException)
    {
        _module = module;
    }

    protected UserModuleActionException(SerializationInfo info, StreamingContext context) 
        : base(info, context)
    {
    }

    public virtual string Module
    {
        get { return _module; }
    }

    public override string Message
    {
        get
        {
            string s = base.Message;
            if (!String.IsNullOrEmpty(_module))
            {
                return s + Environment.NewLine + String.Format("Module: {0}", _module);
            }
            return base.Message;
        }
    }
}

[Serializable]
public class UserActionException : Exception
{
    private readonly string _username;

    public UserActionException()
    {
    }

    public UserActionException(string message)
        : base(message)
    {
    }

    public UserActionException(string message, Exception innerException)
        : base(message, innerException)
    {
    }

    public UserActionException(string message, string username, Exception innerException = null)
        : base(message, innerException)
    {
        _username = username;
    }

    protected UserActionException(SerializationInfo info, StreamingContext context) 
        : base(info, context)
    {
    }

    public override string Message
    {
        get
        {
            string s = base.Message;
            if (!String.IsNullOrEmpty(_username))
            {
                return s + Environment.NewLine + String.Format("Username: {0}", _username);
            }
            return base.Message;
        }
    }

    public virtual string Username
    {
        get { return _username; }
    }
}