IT story

전체 InnerException을 표시하는 올바른 방법은 무엇입니까?

hot-time 2020. 6. 24. 07:28
반응형

전체 InnerException을 표시하는 올바른 방법은 무엇입니까?


내 전체를 표시하는 적절한 방법은 무엇입니까 InnerException.

내 InnerException 중 일부에 다른 예외가 있으며 InnerException꽤 진행되고 있음을 알았습니다 .

InnerException.ToString()나를 위해 일을하거나 내가 통해 루프 필요합니까 InnerExceptions및 최대 구축 String으로 StringBuilder?


간단하게 인쇄 할 수 있습니다 . exception.ToString()중첩 된 모든 텍스트가 포함됩니다 InnerException.


그냥 사용 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())
}    

@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()방법.


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

This recursively goes through all inner exceptions (including the case of AggregateExceptions) to print all Message property contained in them, delimited by line break.

E.g.

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());

Outer aggr ex occurred.
Inner aggr ex.
Number isn't in correct format.
Unauthorized file access.
Not administrator.


You will need to listen to other Exception properties for more details. For e.g. Data will have some information. You could do:

foreach (DictionaryEntry kvp in exception.Data)

To get all derived properties (not on base Exception class), you could do:

exception
    .GetType()
    .GetProperties()
    .Where(p => p.CanRead)
    .Where(p => p.GetMethod.GetBaseDefinition().DeclaringType != typeof(Exception));

If you want information about all exceptions then use exception.ToString(). It will collect data from all inner exceptions.

If you want only the original exception then use exception.GetBaseException().ToString(). This will get you the first exception, e.g. the deepest inner exception or the current exception if there is no inner exception.

Example:

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
}

buildup on nawfal 's answer.

when using his answer there was a missing variable aggrEx, I added it.

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

I do:

namespace System {
  public static class ExtensionMethods {
    public static string FullMessage(this Exception ex) {
      var msg = ex.Message.Replace(", see inner exception.", "").Trim();
      if (ex.InnerException != null) msg += " [" + ex.InnerException.FullMessage() + "]";
      return msg;
    }
  }
}

참고URL : https://stackoverflow.com/questions/5928976/what-is-the-proper-way-to-display-the-full-innerexception

반응형