Как я могу повторно бросить Внутреннее Исключение при поддержании отслеживания стека, сгенерированного до сих пор?

React Native Debugger имеет встроенную функцию.

Просто позвоните showAsyncStorageContentInDev() в консоли RND, и вы увидите дамп хранилища вашего приложения.

19
задан Community 23 May 2017 в 12:24
поделиться

7 ответов

Это - это , возможно сохранение следа стека перед измельчением без отражения:

static void PreserveStackTrace (Exception e)
{
    var ctx = new StreamingContext  (StreamingContextStates.CrossAppDomain) ;
    var mgr = new ObjectManager     (null, ctx) ;
    var si  = new SerializationInfo (e.GetType (), new FormatterConverter ()) ;

    e.GetObjectData    (si, ctx)  ;
    mgr.RegisterObject (e, 1, si) ; // prepare for SetObjectData
    mgr.DoFixups       ()         ; // ObjectManager calls SetObjectData

    // voila, e is unmodified save for _remoteStackTraceString
}

это отходы много циклов по сравнению с InternalPreServestackTack Общественная функциональность. Вот пара общих моделей использования для консервированных функций стопки:

// usage (A): cross-thread invoke, messaging, custom task schedulers etc.
catch (Exception e)
{
    PreserveStackTrace (e) ;

    // store exception to be re-thrown later,
    // possibly in a different thread
    operationResult.Exception = e ;
}

// usage (B): after calling MethodInfo.Invoke() and the like
catch (TargetInvocationException tiex)
{
    PreserveStackTrace (tiex.InnerException) ;

    // unwrap TargetInvocationException, so that typed catch clauses 
    // in library/3rd-party code can work correctly;
    // new stack trace is appended to existing one
    throw tiex.InnerException ;
}
29
ответ дан 30 November 2019 в 03:12
поделиться

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

try
{
    // some code that throws an exception...
}
catch (Exception exception)
{
    FieldInfo remoteStackTraceString = typeof(Exception).GetField("_remoteStackTraceString", BindingFlags.Instance | BindingFlags.NonPublic);
    remoteStackTraceString.SetValue(exception, exception.StackTrace);
    throw exception;
}

Это помещает исходную трассировку стека в поле _remoteStackTraceString исключения, который присоединяется к вновь обнуленной трассировке стека при повторной генерации исключения.

Это действительно ужасный прием , но он позволяет добиться того, чего вы хотите. Вы возитесь с классом System.Exception , поэтому этот метод может выйти из строя в последующих выпусках платформы.

5
ответ дан 30 November 2019 в 03:12
поделиться

Вы не можете этого сделать. throw всегда сбрасывает трассировку стека, если не используется без параметра. Боюсь, вашим абонентам придется использовать InnerException ...

0
ответ дан 30 November 2019 в 03:12
поделиться

Although you may feel that the TargetInvocationException is "useless", it's the reality. Don't try to pretend that .NET didn't take the original exception and wrap it with a TargetInvocationException and throw it. That really happened. Some day, you might even want some piece of information that comes from that wrapping - like maybe the location of the code that threw the TargetInvocationException.

2
ответ дан 30 November 2019 в 03:12
поделиться

Нет, это невозможно. Единственная реальная возможность - следовать рекомендованному шаблону и генерировать собственное исключение с соответствующим InnerException .

Изменить

Если вас беспокоит наличие TargetInvocationException и вы хотите проигнорировать это (не то чтобы я рекомендовал это, так как это может очень хорошо иметь какое-то отношение к тому факту, что он выполняется в другом потоке), тогда ничто не мешает вам бросить здесь свое собственное исключение и прикрепить InnerException из TargetInvocationException как ваше собственное InnerException . Немного вонючий, но вы можете добиться желаемого.

6
ответ дан 30 November 2019 в 03:12
поделиться

Использование ключевого слова throw с исключением всегда будет сбрасывать трассировку стека.

Лучше всего перехватить фактическое исключение, которое вы хотите, и использовать команду throw; вместо "бросить экс;". Или создать собственное исключение с InnerException, которое вы хотите передать.

Я не верю, что то, что вы хотите сделать, возможно.

0
ответ дан 30 November 2019 в 03:12
поделиться

Как говорили другие, используйте ключевое слово "throw" без добавления к нему, чтобы цепочка исключений оставалась нетронутой. Если вам нужно это исходное исключение (при условии, что вы имеете в виду именно это), вы можете вызвать Exception.GetBaseException () в конце вашей цепочки, чтобы получить исключение, с которого все началось.

0
ответ дан 30 November 2019 в 03:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: