Что такое внутреннее исключение
Я прочитал MSDN, но я не мог понять эту концепцию.
Поправь меня, если я ошибаюсь,
Необъяснение будет использоваться в руке с текущим исключением.
Сначала возникнет внутреннее исключение, а затем возникнет текущее исключение (если есть исключение), поэтому InnerException
сверяется с null
, Чтобы сохранить внутреннее исключение, мы должны передать его как параметр.
Я прав с этим?
3 ответа
Вы можете увидеть код ниже.
Первый шаг, я разбираю "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;
}
}
}
Внутренним исключением является исключение, вызвавшее текущее исключение.
Он используется в тех случаях, когда вы хотите отобразить исключение, отличное от того, которое перехватил ваш код, но вы не хотите отбрасывать исходный контекст.
Чтобы новое исключение имело информацию о предыдущем, как вы сказали, вы передаете его в качестве параметра конструктора новому.
Обычно нулевое внутреннее исключение означает, что текущее исключение является основной причиной исключительной ситуации.
Объекты исключений читаются только к тому времени, когда вы 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; }
}
}