What is inner Exception

孤街浪徒 提交于 2019-11-27 01:31:45

问题


I have read the MSDN but, I could not understand this concept.

Correct me if I am wrong,

A innerexception will be used in hand with current exception.

Inner exception will occur first and then the current exception will occur (if there is an exception) that is the reason why InnerException is checked against null. In order to retain inner exception we have to pass it as a parameter.

Am I right with this?


回答1:


You can see the code below.

First step, I parse "abc" to integer. It will raise FormatException.

In the catch block, I try to open a text file to log the exception message. But this file didn't exist. FileNotFoundException will be raised.

I want to know what raised the second exception, so I add the first exception (or FormatException) to the constructor of the second exception.

Now the first exception is InnerException of the second exception.

In the catch block, I can access InnerException's properties to know what the first exception is.

Is it useful?

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



回答2:


An inner exception is the exception that caused the current exception.

It is used in cases when you want to surface a different exception than the one that your code caught but you don't want to throw away the original context.

In order for a new exception to have information about a previous one, like you said, you pass it as constructor parameter to the new one.

Usually, a null inner exception means that the current exception is root cause of the exceptional situation.




回答3:


Exception objects are read only by the time you get to a catch block, sometimes your code can't do anything to handle the exception, but it can add more information by creating a new exception and wrapping the originally thrown exception inside of it. This makes it so you can add information but not be required to copy field by field every piece of information from the original exception (which may not even be possible if you don't know the type of exception that will be thrown).

Here is a slightly modified snippet from a project of mine that uses a bit of everything dealing with Exceptions.

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


来源:https://stackoverflow.com/questions/22826067/what-is-inner-exception

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!