Как проверить, что мой стековый трассер правильно пропускает код библиотеки - PullRequest
0 голосов
/ 30 ноября 2018

У меня вопрос: я пытаюсь пропустить некоторые стековые фреймы, которые поступают из библиотечного кода.Если я хочу проверить это, как мне лучше всего / проще всего вызвать ситуацию, когда на трассировке стека есть один или несколько кадров сверху, взятых из кода библиотеки?

Подробности:

Моя цель с помощью приведенного ниже кода состоит в том, чтобы иметь возможность регистрировать происхождение исключения в моем исходном коде.Тем не менее, в некоторых случаях исключение вызывается в коде библиотеки, поэтому я получаю трассировку стека, которая выглядит следующим образом:

System.Net.WebException: Время ожидания операции
в System.Net истекло.HttpWebRequest.GetRequestStream (TransportContext & context)
в System.Net.HttpWebRequest.GetRequestStream ()
в Microsoft.Bing.Platform.ConversationalUnderstanding.ObjectStore.ObjectStoreClientHelperClass` * *3e) (101) 7- Конец трассировки стека из предыдущего расположения, в котором было сгенерировано исключение ---
в System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw ()
в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (задача задачи)
в Microsoft.Bing.Platform.ConversationalUnderstanding.ObjectStore.ObjectStoreCoprocRequest.d__10`4.MoveNext ()
--- Конец трассировки стека из предыдущего местоположения, где было сгенерировано исключение ---

Итакв основном я хочу двигаться вниз по стековым фреймам, пока не доберусь до места, где у меня естьФактически полезная информация, пропуская методы библиотеки, которые действительно не говорят мне ничего полезного.

Вот код, который я хочу проверить:

public static (string Path, string Method, int Line) TryGetExceptionOrigin(this Exception e, string defaultPath, string defaultMethod, int defaultLine)
{
    var defaultRes = (Path: defaultPath, Method: defaultMethod, Line: defaultLine);
    var st = new StackTrace(e.GetInnerMostException(), true);
    if (st.FrameCount == 0)
    {
        return defaultRes;
    }

    // Walk down the stack, ignoring framework code etc. with no useful information. We need a file name to be happy
    for (int i = 0; i < st.FrameCount; i++)
    {
        var bottomFrame = st.GetFrame(i);
        if (!(string.IsNullOrEmpty(bottomFrame.GetFileName())))
        {
            return (
            Path: bottomFrame.GetFileName() ?? string.Empty, // Is null if no debug information
            Method: bottomFrame.GetMethod().Name, // Documentation does not say this can ever be null
            Line: bottomFrame.GetFileLineNumber()); // Is 0 if no debug information
        }
    }

    // OK no match, we return the default information
    return defaultRes;
}

Ответы [ 2 ]

0 голосов
/ 30 ноября 2018

Нашел его в https://dotnetthoughts.wordpress.com/2007/10/27/where-did-my-exception-occur/

    private static void ThrowIt()
    {
        Divide(3M, 0M);
    }

    static decimal Divide(decimal a, decimal b)
    {
        return (a / b);
    } 

Это приведет к следующей трассировке стека:

st {
в System.Decimal.FCallDivide (десятичное число & d1, десятичное число и d2)
в System.Decimal.op_Division (десятичное d1, десятичное d2)
в ExceptionLogging.Program.Divide (десятичное a, десятичное b) в C: \ Users \ anjohans \ source \ repos \ ExceptionLogging \ ExceptionLogging \ Program.cs: ​​строка 98 в ExceptionLogging.Program.ThrowIt () в C: \ Users \ anjohans \ source \ repos \ ExceptionLogging \ ExceptionLogging \ Program.cs: строка 93 в ExceptionLogging.Program.ThrowLater () в C: \ Users \ anjohans\ source \ repos \ ExceptionLogging \ ExceptionLogging \ Program.cs: строка 88 в ExceptionLogging.Program.Main (String [] args) в C: \ Users \ anjohans \ source \ repos \ ExceptionLogging \ ExceptionLogging \ Program.cs: строка 17}System.Diagnostics.StackTrace

0 голосов
/ 30 ноября 2018

Некоторые излишне запутанные вещи, подобные этой, должны хорошо работать:

try
{
    Func<int> d = () =>
    {
        try
        {
            return Guid.Parse("*").ToByteArray()[0];
        }
        catch (Exception)
        {
            throw;
        }
    };
    Action a = () => { String.Format("{0}", 1 / d()); };
    a();
}
catch (Exception ex)
{
    var useful = ex.TryGetExceptionOrigin(null, null, 0);
}

В этом примере получается стек вызовов исключений с тремя кодами пользователя и четырьмя записями кода инфраструктуры / библиотеки.

...