내 전체를 표시하는 적절한 방법은 무엇입니까 InnerException
.
내 InnerExceptions 중 일부에 다른 예외가 InnerException
있으며 그 점이 상당히 깊다 는 것을 알았습니다 .
윌 InnerException.ToString()
나를 위해 일을하거나 내가 통해 루프 필요합니까 InnerExceptions
및 최대 구축 String
으로 StringBuilder
?
내 전체를 표시하는 적절한 방법은 무엇입니까 InnerException
.
내 InnerExceptions 중 일부에 다른 예외가 InnerException
있으며 그 점이 상당히 깊다 는 것을 알았습니다 .
윌 InnerException.ToString()
나를 위해 일을하거나 내가 통해 루프 필요합니까 InnerExceptions
및 최대 구축 String
으로 StringBuilder
?
답변:
간단하게 인쇄 할 수 있습니다 . exception.ToString()
중첩 된 모든 텍스트가 포함됩니다 InnerException
.
ToString
설명 된대로 내부 예외에 대한 사용자 정의 메소드를 호출하지 않습니다. .
그냥 사용 exception.ToString()
http://msdn.microsoft.com/en-us/library/system.exception.tostring.aspx
ToString의 기본 구현은 현재 예외를 발생시킨 클래스 이름, 메시지, 내부 예외에서 ToString을 호출 한 결과 및 Environment.StackTrace를 호출 한 결과를 얻습니다. 이러한 멤버 중 하나라도 null이면 해당 값이 반환 된 문자열에 포함되지 않습니다.
오류 메시지가 없거나 빈 문자열 ( "")이면 오류 메시지가 반환되지 않습니다. 내부 예외 이름과 스택 추적은 null이 아닌 경우에만 반환됩니다.
exception.ToString () 또한 해당 예외의 내부 예외에 대해 .ToString ()을 호출합니다.
나는 보통 대부분의 소음을 제거하기 위해 이것을 좋아합니다.
void LogException(Exception error) {
Exception realerror = error;
while (realerror.InnerException != null)
realerror = realerror.InnerException;
Console.WriteLine(realerror.ToString())
}
편집 : 나는이 대답을 잊어 버렸고 아무도 할 수 없다는 것을 지적한 사람이 아무도 없습니다
void LogException(Exception error) {
Console.WriteLine(error.GetBaseException().ToString())
}
error.GetBaseException()
. 나는 이것이 같은 일을 믿습니다 ...
@Jon의 답변은 모든 세부 사항 (모든 메시지 및 스택 추적)과 권장되는 것을 원할 때 가장 좋은 솔루션입니다.
그러나 내부 메시지 만 원하는 경우가있을 수 있으며 이러한 경우 다음 확장 방법을 사용합니다.
public static class ExceptionExtensions
{
public static string GetFullMessage(this Exception ex)
{
return ex.InnerException == null
? ex.Message
: ex.Message + " --> " + ex.InnerException.GetFullMessage();
}
}
추적 및 로깅에 대해 다른 리스너가 있고 다른 뷰를 원할 때 종종이 방법을 사용합니다. 그렇게하면 .ToString()
메소드를 사용하여 디버깅을 위해 전자 메일로 스택 추적과 함께 전체 오류를 개발자 팀에 보내는 하나의 리스너와 스택 추적 없이 매일 발생하는 모든 오류 기록과 함께 파일에 로그온하는 리스너를 가질 수 있습니다. .GetFullMessage()
방법.
ex
A는 AggregateException
, 내부 예외 없음이 출력에 포함되지 않는다
Message
깊은 예외의 일부만을 인쇄하려면 다음과 같이 할 수 있습니다.
public static string ToFormattedString(this Exception exception)
{
IEnumerable<string> messages = exception
.GetAllExceptions()
.Where(e => !String.IsNullOrWhiteSpace(e.Message))
.Select(e => e.Message.Trim());
string flattened = String.Join(Environment.NewLine, messages); // <-- the separator here
return flattened;
}
public static IEnumerable<Exception> GetAllExceptions(this Exception exception)
{
yield return exception;
if (exception is AggregateException aggrEx)
{
foreach (Exception innerEx in aggrEx.InnerExceptions.SelectMany(e => e.GetAllExceptions()))
{
yield return innerEx;
}
}
else if (exception.InnerException != null)
{
foreach (Exception innerEx in exception.InnerException.GetAllExceptions())
{
yield return innerEx;
}
}
}
이것은 모든 내부 예외 ( AggregateException
s 의 경우를 포함하여 )를 반복적으로 수행 Message
하여 줄 바꿈으로 구분 된 모든 속성 을 인쇄합니다 .
예 :
var outerAggrEx = new AggregateException(
"Outer aggr ex occurred.",
new AggregateException("Inner aggr ex.", new FormatException("Number isn't in correct format.")),
new IOException("Unauthorized file access.", new SecurityException("Not administrator.")));
Console.WriteLine(outerAggrEx.ToFormattedString());
외부 aggr ex가 발생했습니다.
내부 aggr ex.
숫자가 올바른 형식이 아닙니다.
무단 파일 액세스
관리자가 아닙니다.
자세한 내용은 다른 예외 속성 을 청취해야합니다 . 예를 들어 Data
몇 가지 정보가 있습니다. 당신은 할 수 있습니다 :
foreach (DictionaryEntry kvp in exception.Data)
기본 Exception
클래스가 아닌 파생 속성을 모두 얻으려면 다음을 수행하십시오.
exception
.GetType()
.GetProperties()
.Where(p => p.CanRead)
.Where(p => p.GetMethod.GetBaseDefinition().DeclaringType != typeof(Exception));
IEnumerable<Exception>
하드 코딩 대신 구현되는 속성을 찾아보십시오 AggregrateException
. 또한 문제를 배제 p.IsSpecialName
하고 pi.GetIndexParameters().Length != 0
피하십시오. 출력에서 예외 유형의 이름을 포함하는 것도 좋은 아이디어입니다
나는한다:
namespace System {
public static class ExtensionMethods {
public static string FullMessage(this Exception ex) {
if (ex is AggregateException aex) return aex.InnerExceptions.Aggregate("[ ", (total, next) => $"{total}[{next.FullMessage()}] ") + "]";
var msg = ex.Message.Replace(", see inner exception.", "").Trim();
var innerMsg = ex.InnerException?.FullMessage();
if (innerMsg is object && innerMsg!=msg) msg = $"{msg} [ {innerMsg} ]";
return msg;
}
}
}
이것은 모든 내부 예외를 "인쇄"하고 InnerException.Message가 Message와 같은 AggregateExceptions 및 경우도 처리합니다.
모든 예외에 대한 정보를 원하면을 사용하십시오 exception.ToString()
. 모든 내부 예외에서 데이터를 수집합니다.
원래 예외 만 원하면을 사용하십시오 exception.GetBaseException().ToString()
. 이렇게하면 첫 번째 예외 (예 : 가장 깊은 내부 예외 또는 내부 예외가없는 경우 현재 예외)가 표시됩니다.
예:
try {
Exception ex1 = new Exception( "Original" );
Exception ex2 = new Exception( "Second", ex1 );
Exception ex3 = new Exception( "Third", ex2 );
throw ex3;
} catch( Exception ex ) {
// ex => ex3
Exception baseEx = ex.GetBaseException(); // => ex1
}
nawfal의 답변에 축적.
그의 대답을 사용할 때 누락 된 변수 aggrEx가 있었으므로 추가했습니다.
ExceptionExtenstions.class 파일 :
// example usage:
// try{ ... } catch(Exception e) { MessageBox.Show(e.ToFormattedString()); }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace YourNamespace
{
public static class ExceptionExtensions
{
public static IEnumerable<Exception> GetAllExceptions(this Exception exception)
{
yield return exception;
if (exception is AggregateException )
{
var aggrEx = exception as AggregateException;
foreach (Exception innerEx in aggrEx.InnerExceptions.SelectMany(e => e.GetAllExceptions()))
{
yield return innerEx;
}
}
else if (exception.InnerException != null)
{
foreach (Exception innerEx in exception.InnerException.GetAllExceptions())
{
yield return innerEx;
}
}
}
public static string ToFormattedString(this Exception exception)
{
IEnumerable<string> messages = exception
.GetAllExceptions()
.Where(e => !String.IsNullOrWhiteSpace(e.Message))
.Select(exceptionPart => exceptionPart.Message.Trim() + "\r\n" + (exceptionPart.StackTrace!=null? exceptionPart.StackTrace.Trim():"") );
string flattened = String.Join("\r\n\r\n", messages); // <-- the separator here
return flattened;
}
}
}
e.StackTrace == null