Что такое внутреннее исключение
Я прочитал MSDN, но я не мог понять эту концепцию.
поправьте меня, если я ошибаюсь,
a innerexception будет использоваться в руке с текущим исключением.
сначала произойдет внутреннее исключение, а затем произойдет текущее исключение (если есть исключение), поэтому 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; }
}
}