Catching all java.lang.Error for logging purposes and allowing them to work their way up the stack

泪湿孤枕 提交于 2019-12-11 13:38:09

问题


Short version: How do I catch all java.lang.Error thrown in a particular section of code in order to log them, and also allow them to propogate up the call stack as if I hadn't caught them at all?

Long version...

In a section of code I want to catch all java.lang.Error in order to log them. But I also want to let the Error continue to work its way up the call stack so the behaviour would be the same as if I hadn't caught it at all.

Additionally, I want to catch and log all java.lang.Exceptions and then let them ALSO propogate up the call stack.

I tried this...

    } catch (Throwable e) {
        e.printStackTrace();
        throw e;
    } 

...but the problem with that is I have to modify every method higher up in the call stack to throw Throwable, and some of those methods aren't mine to modify (my method is called by a method in a third party framework).

I would be happy with some kind of wrapping technique, whereby I would put the Throwable in something else and throw that, but I would much prefer to let any java.lang.Errors propogate upward in their natural fashion, as if I hadn't caught them at all.

Suggestions?

EDIT: It was asked "Why do I want to do this?". I think that's a good question which I will clarify: This is a framework for use in my company. It depends on other frameworks contained in jars, that the system admin might have forgotten to include. In that case there is a NoClassDefFoundError in certain places in the code. But only the user sees this Error in the browser, it is not found in the server logs. I want to log it so the system admin can know that this Error has occurred, as he will have instructions for dealing with it.


回答1:


You said: "I tried this..."

    } catch (Throwable e) {
        e.printStackTrace();
        throw e;
    } 

You should try instead:

    } catch (Error e) {
        e.printStackTrace();
        throw e;
    } 

Errors are not checked exceptions. You don't have to declare them in any method signature. Just put that in your outermost method and it will do what you want.

Edit:

If you want to also catch and rethrow Exception, let's think about it. You have three kinds of Throwable: Error, Exception and RuntimeException. Error and RuntimeException are not checked, but Exception which are not RuntimeException are.

So, you can do the same thing for RuntimeException as we do for Error:

    } catch (RuntimeException e) {
        e.printStackTrace();
        throw e;
    } catch (Error e) {
        e.printStackTrace();
        throw e;
    } 

And what about Exception who are not RuntimeException? The thing to understand is that these are checked exceptions and if they are not declared in the methods that the code is calling, then they will not be thrown. So you don't need to catch/rethrow them. If some of the methods called actually throw such an exception, then you will have to catch/rethrow it and mark your method as throwing that exception, but you would have to do that anyway since they are coming from methods the outer method is calling.



来源:https://stackoverflow.com/questions/15190164/catching-all-java-lang-error-for-logging-purposes-and-allowing-them-to-work-thei

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!