What is inner Exception

…衆ロ難τιáo~ 提交于 2019-11-28 06:52:17
Thinh Vu

You can see the code below.

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

In catch block, i try to open text file to log exception message. But this file didn't exist. FileNotFoundException will be raise.

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

Now the first exception is InnerException of the second exception.

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

It's 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;
        }        
    }
}

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.

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