Pergunta

Como parte do tratamento de erros em nosso produto, gostaríamos de descartar algumas informações de rastreamento de pilha.No entanto, percebemos que muitos usuários simplesmente fazem uma captura de tela da caixa de diálogo da mensagem de erro em vez de nos enviar uma cópia do relatório completo disponível no programa e, portanto, gostaria de disponibilizar algumas informações mínimas de rastreamento de pilha nesta caixa de diálogo.

Um rastreamento de pilha .NET em minha máquina é assim:

at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options)
at System.IO.StreamReader..ctor(String path, Encoding encoding, Boolean detectEncodingFromByteOrderMarks, Int32 bufferSize)
at System.IO.StreamReader..ctor(String path)
at LVKWinFormsSandbox.MainForm.button1_Click(Object sender, EventArgs e) in C:\Dev\VS.NET\Gatsoft\LVKWinFormsSandbox\MainForm.cs:line 36

Eu tenho esta pergunta:

O formato parece ser este:

at <class/method> [in file:line ##]

No entanto, o no e em palavras-chave, presumo que elas serão localizadas se executarem, digamos, um tempo de execução .NET norueguês em vez do inglês que instalei.

Existe alguma maneira de separar esse rastreamento de pilha de maneira neutra em termos de linguagem, para que eu possa exibir apenas o arquivo e o número da linha das entradas que possuem isso?

Em outras palavras, gostaria dessas informações do texto acima:

C:\Dev\VS.NET\Gatsoft\LVKWinFormsSandbox\MainForm.cs:line 36

Qualquer conselho que você possa dar será útil.

Foi útil?

Solução

Você deve conseguir obter um objeto StackTrace em vez de uma string dizendo

var trace = new System.Diagnostics.StackTrace(exception);

Você mesmo pode ver os frames sem depender da formatação do framework.

Veja também: Referência StackTrace

Outras dicas

Aqui está o código que uso para fazer isso sem exceção

public static void LogStack()
{
  var trace = new System.Diagnostics.StackTrace();
  foreach (var frame in trace.GetFrames())
  {
    var method = frame.GetMethod();
    if (method.Name.Equals("LogStack")) continue;
    Log.Debug(string.Format("{0}::{1}", 
        method.ReflectedType != null ? method.ReflectedType.Name : string.Empty,
        method.Name));
  }
}

Apenas para tornar esta uma resposta de copiar e colar de 15 segundos:

static public string StackTraceToString()
{
    StringBuilder sb = new StringBuilder(256);
    var frames = new System.Diagnostics.StackTrace().GetFrames();
    for (int i = 1; i < frames.Length; i++) /* Ignore current StackTraceToString method...*/
    {
        var currFrame = frames[i];
        var method = currFrame.GetMethod();
        sb.AppendLine(string.Format("{0}:{1}",                    
            method.ReflectedType != null ? method.ReflectedType.Name : string.Empty,
            method.Name));
    }
    return sb.ToString();
}

(com base na resposta de Lindholm)

Ou há uma versão ainda mais curta.

Console.Write(exception.StackTrace);

Como alternativa, o log4net, embora potencialmente perigoso, me deu melhores resultados que o System.Diagnostics.Basicamente no log4net, você tem um método para os vários níveis de log, cada um com um parâmetro Exception.Portanto, quando você passar a segunda exceção, ele imprimirá o rastreamento de pilha para qualquer anexador que você configurou.

exemplo: Logger.Error("Danger!!!", myException );

A saída, dependendo da configuração, é semelhante a

System.ApplicationException: Something went wrong.
   at Adapter.WriteToFile(OleDbCommand cmd) in C:\Adapter.vb:line 35
   at Adapter.GetDistributionDocument(Int32 id) in C:\Adapter.vb:line 181
   ...
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top