简体   繁体   English

将 StackTrace 附加到异常而不抛出 C#/.NET

[英]Attach StackTrace To Exception Without Throwing in C# / .NET

I have a component which handles errors using return values as opposed to standard exception handling.我有一个组件,它使用返回值而不是标准异常处理来处理错误。 In addition to the error code, it also returns a stack trace of where the error has occurred.除了错误代码之外,它还返回错误发生位置的堆栈跟踪。 A wrapper I use to invoke the component will interpret return codes and throw an exception.我用来调用组件的包装器将解释返回码并抛出异常。

I'd like to have the wrapper throw an exception that includes the captured stack trace information from the component.我想让包装器抛出一个异常,其中包括从组件中捕获的堆栈跟踪信息。 I'd like it to appear as if the exception had been thrown from the original site of the error even though it was thrown elsewhere.我希望它看起来好像异常是从错误的原始站点抛出的,即使它是在其他地方抛出的。 More specifically, I'd like the stack trace displayed by the Visual Studio test runner to reflect the proper location.更具体地说,我希望 Visual Studio 测试运行程序显示的堆栈跟踪反映正确的位置。

Is there any way to do this?有没有办法做到这一点? It would also be nice if I could avoid low-level reflection tricks accessing private members but I will take what I can get.如果我能避免访问私有成员的低级反射技巧也很好,但我会尽我所能。

I'm not concerned with how to capture a stack trace, I'm concerned with attaching a stack trace that's already been captured, to an Exception.我不关心如何捕获堆栈跟踪,我关心的是将已捕获的堆栈跟踪附加到异常。

I tried overriding the StackTrace property, but Visual Studio is pulling the stack trace data from somewhere else, and seems to ignore the overridden property completely我尝试覆盖 StackTrace 属性,但 Visual Studio 正在从其他地方提取堆栈跟踪数据,并且似乎完全忽略了被覆盖的属性

CustomException GenerateExcpetion()
{
    return new CustomException();
}

void ThrowException(Exception ex)
{
    Trace.WriteLine("Displaying Exception");
    Trace.WriteLine(ex.ToString());
    var edi = ExceptionDispatchInfo.Capture(ex);
    edi.Throw();
}

[TestMethod]
public void Test006()
{
    var ex = GenerateExcpetion();
    ThrowException(ex);
}

public class CustomException : Exception
{
    string _stackTrace;
    public CustomException()
    {
        _stackTrace = Environment.StackTrace;
    }

    public override string StackTrace
    {
        get
        {
            return base.StackTrace;
        }
    }
}

The Exception.ToString() method pulls stack trace data from a private property, and so the stack trace coming from the override doesn't get shown. Exception.ToString()方法从私有属性中提取堆栈跟踪数据,因此不会显示来自覆盖的堆栈跟踪。

CustomException: Exception of type 'CustomException' was thrown. CustomException: 抛出了“CustomException”类型的异常。

The ExceptionDispatchInfo looks for the stack trace data from a private property as well, and so it can't find any of that data, and when you throw this custom exception a new stack trace is attached to the exception with the location that it is being thrown from. ExceptionDispatchInfo 也从私有属性中查找堆栈跟踪数据,因此它找不到任何该数据,并且当您抛出此自定义异常时,一个新的堆栈跟踪会附加到该异常所在的位置从。 If you use throw directly, the private stack information is set to the place where the throw happened.如果直接使用throw,私有栈信息设置为throw发生的地方。

I have a component which handles errors using return values as opposed to standard exception handling.我有一个组件,该组件使用返回值(而不是标准异常处理)来处理错误。 In addition to the error code, it also returns a stack trace of where the error has occurred.除了错误代码,它还返回错误发生位置的堆栈跟踪。 A wrapper I use to invoke the component will interpret return codes and throw an exception.我用来调用组件的包装器将解释返回码并引发异常。

I'd like to have the wrapper throw an exception that includes the captured stack trace information from the component.我想让包装器引发一个异常,该异常包括从组件捕获的堆栈跟踪信息。 I'd like it to appear as if the exception had been thrown from the original site of the error even though it was thrown elsewhere.我希望它看起来好像是从错误的原始位置抛出了异常,即使它是在其他地方抛出的也是如此。 More specifically, I'd like the stack trace displayed by the Visual Studio test runner to reflect the proper location.更具体地说,我希望Visual Studio测试运行器显示的堆栈跟踪信息可以反映正确的位置。

Is there any way to do this?有什么办法吗? It would also be nice if I could avoid low-level reflection tricks accessing private members but I will take what I can get.如果我可以避免使用低级反射技巧来访问私有成员,那也很好,但我会尽我所能。

I'm not concerned with how to capture a stack trace, I'm concerned with attaching a stack trace that's already been captured, to an Exception.我不关心如何捕获堆栈跟踪,我不关心将已捕获的堆栈跟踪附加到Exception。

I tried overriding the StackTrace property, but Visual Studio is pulling the stack trace data from somewhere else, and seems to ignore the overridden property completely我尝试覆盖StackTrace属性,但是Visual Studio正在从其他位置提取堆栈跟踪数据,并且似乎完全忽略了重写的属性

CustomException GenerateExcpetion()
{
    return new CustomException();
}

void ThrowException(Exception ex)
{
    Trace.WriteLine("Displaying Exception");
    Trace.WriteLine(ex.ToString());
    var edi = ExceptionDispatchInfo.Capture(ex);
    edi.Throw();
}

[TestMethod]
public void Test006()
{
    var ex = GenerateExcpetion();
    ThrowException(ex);
}

public class CustomException : Exception
{
    string _stackTrace;
    public CustomException()
    {
        _stackTrace = Environment.StackTrace;
    }

    public override string StackTrace
    {
        get
        {
            return base.StackTrace;
        }
    }
}

The Exception.ToString() method pulls stack trace data from a private property, and so the stack trace coming from the override doesn't get shown. Exception.ToString()方法从私有属性中提取堆栈跟踪数据,因此不会显示来自覆盖的堆栈跟踪。

CustomException: Exception of type 'CustomException' was thrown. CustomException:引发了'CustomException'类型的异常。

The ExceptionDispatchInfo looks for the stack trace data from a private property as well, and so it can't find any of that data, and when you throw this custom exception a new stack trace is attached to the exception with the location that it is being thrown from. ExceptionDispatchInfo也从私有属性中查找堆栈跟踪数据,因此它找不到任何数据,并且当您抛出此自定义异常时,会将新的堆栈跟踪附加到该异常,并在其位置进行定位。从抛出。 If you use throw directly, the private stack information is set to the place where the throw happened.如果直接使用throw,则将私有堆栈信息设置为发生throw的位置。

I have a component which handles errors using return values as opposed to standard exception handling.我有一个组件,该组件使用返回值(而不是标准异常处理)来处理错误。 In addition to the error code, it also returns a stack trace of where the error has occurred.除了错误代码,它还返回错误发生位置的堆栈跟踪。 A wrapper I use to invoke the component will interpret return codes and throw an exception.我用来调用组件的包装器将解释返回码并引发异常。

I'd like to have the wrapper throw an exception that includes the captured stack trace information from the component.我想让包装器引发一个异常,该异常包括从组件捕获的堆栈跟踪信息。 I'd like it to appear as if the exception had been thrown from the original site of the error even though it was thrown elsewhere.我希望它看起来好像是从错误的原始位置抛出了异常,即使它是在其他地方抛出的也是如此。 More specifically, I'd like the stack trace displayed by the Visual Studio test runner to reflect the proper location.更具体地说,我希望Visual Studio测试运行器显示的堆栈跟踪信息可以反映正确的位置。

Is there any way to do this?有什么办法吗? It would also be nice if I could avoid low-level reflection tricks accessing private members but I will take what I can get.如果我可以避免使用低级反射技巧来访问私有成员,那也很好,但我会尽我所能。

I'm not concerned with how to capture a stack trace, I'm concerned with attaching a stack trace that's already been captured, to an Exception.我不关心如何捕获堆栈跟踪,我不关心将已捕获的堆栈跟踪附加到Exception。

I tried overriding the StackTrace property, but Visual Studio is pulling the stack trace data from somewhere else, and seems to ignore the overridden property completely我尝试覆盖StackTrace属性,但是Visual Studio正在从其他位置提取堆栈跟踪数据,并且似乎完全忽略了重写的属性

CustomException GenerateExcpetion()
{
    return new CustomException();
}

void ThrowException(Exception ex)
{
    Trace.WriteLine("Displaying Exception");
    Trace.WriteLine(ex.ToString());
    var edi = ExceptionDispatchInfo.Capture(ex);
    edi.Throw();
}

[TestMethod]
public void Test006()
{
    var ex = GenerateExcpetion();
    ThrowException(ex);
}

public class CustomException : Exception
{
    string _stackTrace;
    public CustomException()
    {
        _stackTrace = Environment.StackTrace;
    }

    public override string StackTrace
    {
        get
        {
            return base.StackTrace;
        }
    }
}

The Exception.ToString() method pulls stack trace data from a private property, and so the stack trace coming from the override doesn't get shown. Exception.ToString()方法从私有属性中提取堆栈跟踪数据,因此不会显示来自覆盖的堆栈跟踪。

CustomException: Exception of type 'CustomException' was thrown. CustomException:引发了'CustomException'类型的异常。

The ExceptionDispatchInfo looks for the stack trace data from a private property as well, and so it can't find any of that data, and when you throw this custom exception a new stack trace is attached to the exception with the location that it is being thrown from. ExceptionDispatchInfo也从私有属性中查找堆栈跟踪数据,因此它找不到任何数据,并且当您抛出此自定义异常时,会将新的堆栈跟踪附加到该异常,并在其位置进行定位。从抛出。 If you use throw directly, the private stack information is set to the place where the throw happened.如果直接使用throw,则将私有堆栈信息设置为发生throw的位置。

I have a component which handles errors using return values as opposed to standard exception handling.我有一个组件,该组件使用返回值(而不是标准异常处理)来处理错误。 In addition to the error code, it also returns a stack trace of where the error has occurred.除了错误代码,它还返回错误发生位置的堆栈跟踪。 A wrapper I use to invoke the component will interpret return codes and throw an exception.我用来调用组件的包装器将解释返回码并引发异常。

I'd like to have the wrapper throw an exception that includes the captured stack trace information from the component.我想让包装器引发一个异常,该异常包括从组件捕获的堆栈跟踪信息。 I'd like it to appear as if the exception had been thrown from the original site of the error even though it was thrown elsewhere.我希望它看起来好像是从错误的原始位置抛出了异常,即使它是在其他地方抛出的也是如此。 More specifically, I'd like the stack trace displayed by the Visual Studio test runner to reflect the proper location.更具体地说,我希望Visual Studio测试运行器显示的堆栈跟踪信息可以反映正确的位置。

Is there any way to do this?有什么办法吗? It would also be nice if I could avoid low-level reflection tricks accessing private members but I will take what I can get.如果我可以避免使用低级反射技巧来访问私有成员,那也很好,但我会尽我所能。

I'm not concerned with how to capture a stack trace, I'm concerned with attaching a stack trace that's already been captured, to an Exception.我不关心如何捕获堆栈跟踪,我不关心将已捕获的堆栈跟踪附加到Exception。

I tried overriding the StackTrace property, but Visual Studio is pulling the stack trace data from somewhere else, and seems to ignore the overridden property completely我尝试覆盖StackTrace属性,但是Visual Studio正在从其他位置提取堆栈跟踪数据,并且似乎完全忽略了重写的属性

CustomException GenerateExcpetion()
{
    return new CustomException();
}

void ThrowException(Exception ex)
{
    Trace.WriteLine("Displaying Exception");
    Trace.WriteLine(ex.ToString());
    var edi = ExceptionDispatchInfo.Capture(ex);
    edi.Throw();
}

[TestMethod]
public void Test006()
{
    var ex = GenerateExcpetion();
    ThrowException(ex);
}

public class CustomException : Exception
{
    string _stackTrace;
    public CustomException()
    {
        _stackTrace = Environment.StackTrace;
    }

    public override string StackTrace
    {
        get
        {
            return base.StackTrace;
        }
    }
}

The Exception.ToString() method pulls stack trace data from a private property, and so the stack trace coming from the override doesn't get shown. Exception.ToString()方法从私有属性中提取堆栈跟踪数据,因此不会显示来自覆盖的堆栈跟踪。

CustomException: Exception of type 'CustomException' was thrown. CustomException:引发了'CustomException'类型的异常。

The ExceptionDispatchInfo looks for the stack trace data from a private property as well, and so it can't find any of that data, and when you throw this custom exception a new stack trace is attached to the exception with the location that it is being thrown from. ExceptionDispatchInfo也从私有属性中查找堆栈跟踪数据,因此它找不到任何数据,并且当您抛出此自定义异常时,会将新的堆栈跟踪附加到该异常,并在其位置进行定位。从抛出。 If you use throw directly, the private stack information is set to the place where the throw happened.如果直接使用throw,则将私有堆栈信息设置为发生throw的位置。

I have a component which handles errors using return values as opposed to standard exception handling.我有一个组件,该组件使用返回值(而不是标准异常处理)来处理错误。 In addition to the error code, it also returns a stack trace of where the error has occurred.除了错误代码,它还返回错误发生位置的堆栈跟踪。 A wrapper I use to invoke the component will interpret return codes and throw an exception.我用来调用组件的包装器将解释返回码并引发异常。

I'd like to have the wrapper throw an exception that includes the captured stack trace information from the component.我想让包装器引发一个异常,该异常包括从组件捕获的堆栈跟踪信息。 I'd like it to appear as if the exception had been thrown from the original site of the error even though it was thrown elsewhere.我希望它看起来好像是从错误的原始位置抛出了异常,即使它是在其他地方抛出的也是如此。 More specifically, I'd like the stack trace displayed by the Visual Studio test runner to reflect the proper location.更具体地说,我希望Visual Studio测试运行器显示的堆栈跟踪信息可以反映正确的位置。

Is there any way to do this?有什么办法吗? It would also be nice if I could avoid low-level reflection tricks accessing private members but I will take what I can get.如果我可以避免使用低级反射技巧来访问私有成员,那也很好,但我会尽我所能。

I'm not concerned with how to capture a stack trace, I'm concerned with attaching a stack trace that's already been captured, to an Exception.我不关心如何捕获堆栈跟踪,我不关心将已捕获的堆栈跟踪附加到Exception。

I tried overriding the StackTrace property, but Visual Studio is pulling the stack trace data from somewhere else, and seems to ignore the overridden property completely我尝试覆盖StackTrace属性,但是Visual Studio正在从其他位置提取堆栈跟踪数据,并且似乎完全忽略了重写的属性

CustomException GenerateExcpetion()
{
    return new CustomException();
}

void ThrowException(Exception ex)
{
    Trace.WriteLine("Displaying Exception");
    Trace.WriteLine(ex.ToString());
    var edi = ExceptionDispatchInfo.Capture(ex);
    edi.Throw();
}

[TestMethod]
public void Test006()
{
    var ex = GenerateExcpetion();
    ThrowException(ex);
}

public class CustomException : Exception
{
    string _stackTrace;
    public CustomException()
    {
        _stackTrace = Environment.StackTrace;
    }

    public override string StackTrace
    {
        get
        {
            return base.StackTrace;
        }
    }
}

The Exception.ToString() method pulls stack trace data from a private property, and so the stack trace coming from the override doesn't get shown. Exception.ToString()方法从私有属性中提取堆栈跟踪数据,因此不会显示来自覆盖的堆栈跟踪。

CustomException: Exception of type 'CustomException' was thrown. CustomException:引发了'CustomException'类型的异常。

The ExceptionDispatchInfo looks for the stack trace data from a private property as well, and so it can't find any of that data, and when you throw this custom exception a new stack trace is attached to the exception with the location that it is being thrown from. ExceptionDispatchInfo也从私有属性中查找堆栈跟踪数据,因此它找不到任何数据,并且当您抛出此自定义异常时,会将新的堆栈跟踪附加到该异常,并在其位置进行定位。从抛出。 If you use throw directly, the private stack information is set to the place where the throw happened.如果直接使用throw,则将私有堆栈信息设置为发生throw的位置。

I have a component which handles errors using return values as opposed to standard exception handling.我有一个组件,该组件使用返回值(而不是标准异常处理)来处理错误。 In addition to the error code, it also returns a stack trace of where the error has occurred.除了错误代码,它还返回错误发生位置的堆栈跟踪。 A wrapper I use to invoke the component will interpret return codes and throw an exception.我用来调用组件的包装器将解释返回码并引发异常。

I'd like to have the wrapper throw an exception that includes the captured stack trace information from the component.我想让包装器引发一个异常,该异常包括从组件捕获的堆栈跟踪信息。 I'd like it to appear as if the exception had been thrown from the original site of the error even though it was thrown elsewhere.我希望它看起来好像是从错误的原始位置抛出了异常,即使它是在其他地方抛出的也是如此。 More specifically, I'd like the stack trace displayed by the Visual Studio test runner to reflect the proper location.更具体地说,我希望Visual Studio测试运行器显示的堆栈跟踪信息可以反映正确的位置。

Is there any way to do this?有什么办法吗? It would also be nice if I could avoid low-level reflection tricks accessing private members but I will take what I can get.如果我可以避免使用低级反射技巧来访问私有成员,那也很好,但我会尽我所能。

I'm not concerned with how to capture a stack trace, I'm concerned with attaching a stack trace that's already been captured, to an Exception.我不关心如何捕获堆栈跟踪,我不关心将已捕获的堆栈跟踪附加到Exception。

I tried overriding the StackTrace property, but Visual Studio is pulling the stack trace data from somewhere else, and seems to ignore the overridden property completely我尝试覆盖StackTrace属性,但是Visual Studio正在从其他位置提取堆栈跟踪数据,并且似乎完全忽略了重写的属性

CustomException GenerateExcpetion()
{
    return new CustomException();
}

void ThrowException(Exception ex)
{
    Trace.WriteLine("Displaying Exception");
    Trace.WriteLine(ex.ToString());
    var edi = ExceptionDispatchInfo.Capture(ex);
    edi.Throw();
}

[TestMethod]
public void Test006()
{
    var ex = GenerateExcpetion();
    ThrowException(ex);
}

public class CustomException : Exception
{
    string _stackTrace;
    public CustomException()
    {
        _stackTrace = Environment.StackTrace;
    }

    public override string StackTrace
    {
        get
        {
            return base.StackTrace;
        }
    }
}

The Exception.ToString() method pulls stack trace data from a private property, and so the stack trace coming from the override doesn't get shown. Exception.ToString()方法从私有属性中提取堆栈跟踪数据,因此不会显示来自覆盖的堆栈跟踪。

CustomException: Exception of type 'CustomException' was thrown. CustomException:引发了'CustomException'类型的异常。

The ExceptionDispatchInfo looks for the stack trace data from a private property as well, and so it can't find any of that data, and when you throw this custom exception a new stack trace is attached to the exception with the location that it is being thrown from. ExceptionDispatchInfo也从私有属性中查找堆栈跟踪数据,因此它找不到任何数据,并且当您抛出此自定义异常时,会将新的堆栈跟踪附加到该异常,并在其位置进行定位。从抛出。 If you use throw directly, the private stack information is set to the place where the throw happened.如果直接使用throw,则将私有堆栈信息设置为发生throw的位置。

Just add the following to your custom exception:只需将以下内容添加到您的自定义异常中:

public override string StackTrace => base.StackTrace ?? Environment.StackTrace;

The StackTrace property is filled when an exception is thrown.引发异常时填充StackTrace属性。

Hence, if you instantiate a custom exception for logging purposes and it is never thrown, the StackTrace remains null .因此,如果您出于日志记录目的实例化自定义异常并且它从不抛出,则StackTrace保持为null

This simple override fills the StackTrace in this case so the exception context is clearer for logging purposes without having to incur the high overhead of throwing an exception if it is unnecessary.在这种情况下,这个简单的覆盖填充了StackTrace ,因此异常上下文对于记录目的更加清晰,而不必承担在不必要时抛出异常的高开销。

I have a component which handles errors using return values as opposed to standard exception handling.我有一个组件,该组件使用返回值(而不是标准异常处理)来处理错误。 In addition to the error code, it also returns a stack trace of where the error has occurred.除了错误代码,它还返回错误发生位置的堆栈跟踪。 A wrapper I use to invoke the component will interpret return codes and throw an exception.我用来调用组件的包装器将解释返回码并引发异常。

I'd like to have the wrapper throw an exception that includes the captured stack trace information from the component.我想让包装器引发一个异常,该异常包括从组件捕获的堆栈跟踪信息。 I'd like it to appear as if the exception had been thrown from the original site of the error even though it was thrown elsewhere.我希望它看起来好像是从错误的原始位置抛出了异常,即使它是在其他地方抛出的也是如此。 More specifically, I'd like the stack trace displayed by the Visual Studio test runner to reflect the proper location.更具体地说,我希望Visual Studio测试运行器显示的堆栈跟踪信息可以反映正确的位置。

Is there any way to do this?有什么办法吗? It would also be nice if I could avoid low-level reflection tricks accessing private members but I will take what I can get.如果我可以避免使用低级反射技巧来访问私有成员,那也很好,但我会尽我所能。

I'm not concerned with how to capture a stack trace, I'm concerned with attaching a stack trace that's already been captured, to an Exception.我不关心如何捕获堆栈跟踪,我不关心将已捕获的堆栈跟踪附加到Exception。

I tried overriding the StackTrace property, but Visual Studio is pulling the stack trace data from somewhere else, and seems to ignore the overridden property completely我尝试覆盖StackTrace属性,但是Visual Studio正在从其他位置提取堆栈跟踪数据,并且似乎完全忽略了重写的属性

CustomException GenerateExcpetion()
{
    return new CustomException();
}

void ThrowException(Exception ex)
{
    Trace.WriteLine("Displaying Exception");
    Trace.WriteLine(ex.ToString());
    var edi = ExceptionDispatchInfo.Capture(ex);
    edi.Throw();
}

[TestMethod]
public void Test006()
{
    var ex = GenerateExcpetion();
    ThrowException(ex);
}

public class CustomException : Exception
{
    string _stackTrace;
    public CustomException()
    {
        _stackTrace = Environment.StackTrace;
    }

    public override string StackTrace
    {
        get
        {
            return base.StackTrace;
        }
    }
}

The Exception.ToString() method pulls stack trace data from a private property, and so the stack trace coming from the override doesn't get shown. Exception.ToString()方法从私有属性中提取堆栈跟踪数据,因此不会显示来自覆盖的堆栈跟踪。

CustomException: Exception of type 'CustomException' was thrown. CustomException:引发了'CustomException'类型的异常。

The ExceptionDispatchInfo looks for the stack trace data from a private property as well, and so it can't find any of that data, and when you throw this custom exception a new stack trace is attached to the exception with the location that it is being thrown from. ExceptionDispatchInfo也从私有属性中查找堆栈跟踪数据,因此它找不到任何数据,并且当您抛出此自定义异常时,会将新的堆栈跟踪附加到该异常,并在其位置进行定位。从抛出。 If you use throw directly, the private stack information is set to the place where the throw happened.如果直接使用throw,则将私有堆栈信息设置为发生throw的位置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM