简体   繁体   English

在finally块中引发异常

[英]Get thrown exception in finally block

Is there a way, how to get currently thrown exception (if exists)? 有没有一种方法,如何获取当前引发的异常(如果存在)?

I would like reduce amount of code and apply some reuse for task looks like: 我想减少代码量并为任务应用一些重用:

Exception thrownException = null;
try {
    // some code with 3rd party classes, which can throw unexpected exceptions
}
catch( Exception exc ) {
    thrownException = exc;
    LogException( exc );
}
finally {
    if ( null == thrownException ) {
        // some code
    }
    else {
        // some code
    }
}

and replace it with this code: 并替换为以下代码:

using( ExceptionHelper.LogException() ) {
    // some code with 3rd party classes, which can throw unexpected exceptions
}
using( new ExceptionHelper { ExceptionAction = ()=> /*some cleaning code*/ } ) {
    // some code with 3rd party classes, which can throw unexpected exceptions
}

public class ExceptiohHelper : IDisposable {
    public static ExceptionHelper LogException() {
        return new ExceptionHelper();
    }

    public Action SuccessfulAction {get; set;}
    public Action ExceptionAction {get; set;}

    public void Dispose() {
        Action action;
        Exception thrownException = TheMethodIDontKnow();
        if ( null != thrownException ) {
            LogException( thrownException );
            action = this.ExceptionAction;
        }
        else {
            action = this.SuccessfulAction;
        }

        if ( null != action ) {
            action();
        }
    }
}

Is this scenario posible? 这种情况可行吗?

Thanks 谢谢

The idea is that you handle exceptions in the catch block... 这个想法是您在catch块中处理异常。

That said, Exception is a reference type, so you can always declare an Exception variable outside the try scope... 就是说,Exception是一个引用类型,因此您总是可以在try范围之外声明一个Exception变量。

Exception dontDoThis;
try
{
    foo.DoSomething();
}
catch(Exception e)
{
    dontDoThis = e;
}
finally
{
    // use dontDoThis...
}

What do you think about the following. 您如何看待以下内容。 Instead of looking at the problem as "How to get the last exception?", what if you change it to, "How do I run some piece of code with some more control?" 与其将问题视为“如何获取最后一个异常?”,不如将其更改为“如何通过更多控制来运行一段代码?”。

For example: Instead of an ExceptionHelper you could have an ActionRunner. 例如:您可以使用ActionRunner代替ExceptionHelper。

public class ActionRunner
{
    public Action AttemptAction { get; set; }
    public Action SuccessfulAction { get; set; }
    public Action ExceptionAction { get; set; }

    public void RunAction()
    {
        try
        {
            AttemptAction();
            SuccessfulAction();
        }
        catch (Exception ex)
        {
            LogException(ex);
            ExceptionAction();
        }
    }

    private void LogException(Exception thrownException) { /* log here... */ }
}

It would at least give you some reuse of the SuccessfulAction and ExceptionAction assuming only the AttemptAction varies between calls. 假设只有AttemptAction在两次调用之间有所不同,它将至少使您成功重用SuccessActionAction和ExceptionAction。

var actionRunner = new ActionRunner
{
    AttemptAction = () =>
    {
        Console.WriteLine("Going to throw...");
        throw new Exception("Just throwing");
    },
    ExceptionAction = () => Console.WriteLine("ExceptionAction"),
    SuccessfulAction = () => Console.WriteLine("SuccessfulAction"),
};
actionRunner.RunAction();

actionRunner.AttemptAction = () => Console.WriteLine("Running some other code...");
actionRunner.RunAction();

If you are looking to catch unexpected exceptions you should be handling the UnhandledException . 如果您希望捕获意外的异常,则应该处理UnhandledException You should only catch exceptions at lower levels that you intend handle (not just to log), otherwise you should let them bubble up and be caught at a higher level, or as I mentioned before in the UnhandledException method. 您应该只捕获打算处理的较低级别的异常(而不仅仅是记录),否则,应该让它们冒泡并被捕获到较高的级别,或者正如我在UnhandledException方法中提到的那样。

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

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