简体   繁体   English

无法处理的Java异常

[英]Java Exceptions that cannot be handled

I frequently come across the same problem. 我经常遇到相同的问题。 At the very core of my Java Application, I have methods that throw an exception which cannot be handled by any method caller. 在Java应用程序的核心部分,我有抛出异常的方法,任何方法调用者都无法处理该异常。 I have to bubble those exceptions up to the main method. 我必须将那些异常冒泡到主要方法上。 All those exception summarize so I have many throws statements on higher levels of my Application. 所有这些异常都进行了总结,因此我在应用程序的更高级别上有很多throw语句。

Eg I have a NodeJsManager.java class at the core of my application: 例如,我在应用程序的核心处有一个NodeJsManager.java类:

public class NodeJsManager {

    public static void startNodeJs() throws ExecuteException {
        // Code to start NodeJs Server goes here
    }

}

To start the NodeJs Server, I have to execute something on command line. 要启动NodeJs Server,我必须在命令行上执行一些操作。 I can do that with the apache class org.apache.commons.exec.CommandLine . 我可以使用apache类org.apache.commons.exec.CommandLine做到这一点。 But it throws an ExecuteException, if the execution exited with an error code. 但是,如果执行以错误代码退出,则会抛出ExecuteException。 Without NodeJs being started my application is useless. 如果没有启动NodeJ,我的应用程序将毫无用处。 No method can catch this exception, it is just a requirement for my application to work. 没有任何方法可以捕获此异常,这只是我的应用程序正常运行的要求 So the exception will bubble up almost the whole application lifecycle. 因此,异常将使几乎整个应用程序生命周期冒泡。 I have other Managers that do the same (a ConfigurationManager that throws an exception, if the config path is wrong). 我还有其他管理器也执行相同的操作(如果配置路径错误,则ConfigurationManager会引发异常)。 All together it summarizes in many throws statements at every single method on a higher level where I don't even remember the cause of that exception. 总之,它在更高级别上的每个方法的许多throws语句中进行了总结,我什至不记得该异常的原因。

How would you handle that problem? 您将如何处理该问题? I must do something completely wrong because I can't find similar posts that describe my problem! 我必须做完全错误的事情,因为找不到类似的帖子来描述我的问题!

Regards Mike 问候迈克

Update 更新

I just unearthed my good old Effective Java book. 我刚刚发掘了我的老有效Java书籍。 The Author (a Java architect at Google) wrote the following about Exceptions: 作者(Google的Java架构师)针对异常编写了以下内容:

... use checked exceptions for recoverable conditions and runtime exceptions for programming errors. ...将检查的异常用于可恢复的条件,将运行时异常用于编程错误。

... ...

If it isn't clear whether recovery is possible, you're probably better off using an unchecked exception ... 如果不清楚是否可以进行恢复,则最好使用未检查的异常...

In my case it is clearly not recoverable, so throwing a runtime exception is the way to go. 就我而言,它显然不可恢复,因此抛出运行时异常是可行的方法。 I always thought runtime exceptions should be prevented, this changes my point of view about exceptions in Java. 我一直认为应该避免运行时异常,这改变了我对Java异常的看法。

One possible approach is to deal with the Exception as close as possible to where it originated, where you have enough information to make a decision on what to do. 一种可能的方法是,尽可能在Exception地方(您有足够的信息来决定要做什么)处理Exception

As you said if you have all the Exception s caught at the highest level possible you are losing the context which is really important, because that gives information on why and how the problem occurred (and hopefully a few ways to fix it). 如您所说,如果所有Exception都在最高级别被捕获,那么您将失去真正重要的上下文,因为这可以提供有关问题原因和发生方式的信息(并希望有一些解决方法)。

You said for example that your application without a NodeJS server is useless, then probably a way of doing this would be to have the NodeJSManager (if such a thing exists :D, I'm guessing) to not throw, but prevent the application from starting at all, something like 例如,您说没有NodeJS服务器的应用程序是无用的,那么执行此操作的一种方法可能是不要抛出NodeJSManager (如果存在这样的东西:D,我想是),但是会阻止应用程序从根本上开始,像

NodeJSManager nodejsManager = new NodeJSManager();
boolean succeeded = nodejsManager.tryToStart();
if (!succeeded) {
    // guard, it's useless to proceed
    // cleanup and exit
}

I called that method tryToStart because it can happen that the server does not start, you are dealing directly with the executables and the file system so I would say this is not so exceptional any more (but probably this is just a matter of taste). tryToStart方法, tryToStart因为它可能会发生服务器无法启动,您直接处理可执行文件和文件系统的情况,因此我想说这不再是例外了(但可能只是一个问题)。

What's important IMHO is that you specify your application start up as a series of checks, for example the node and the configuration ones, without having to deal with Exception s to handle the flow of your code. 恕我直言,重要的是您可以指定应用程序启动为一系列检查,例如节点和配置检查,而无需处理Exception来处理代码流。

I don't like checked Exceptions. 我不喜欢检查异常。 What I use to do (but is NOT a nice solution) is to catch the checked Exception and re-throw it as a Runtime Exception this way: 我要做的(但不是一个很好的解决方案)是捕获已检查的异常,然后通过以下方式将其重新抛出为运行时异常:

catch (ExecuteException e) {
    throw new RuntimeException (e);
}

The checked Exception "e" is passed as an parameter to RuntimeException. 选中的异常“ e”作为参数传递给RuntimeException。 This way, I convert a checked into an unchecked exception. 这样,我将一个已检查的异常转换为一个未检查的异常。 But as I said, is not a nice solution and it may cause more debugging problems that it solves. 但是,正如我所说,这不是一个很好的解决方案,它可能会导致更多调试问题解决。 When an Exception is "checked" it tends to be because the error described is "serious". “检查”异常时,往往是因为所描述的错误是“严重的”。

One solution would be to create your own, more general exception class that will extends Exception and wrap unhandled exceptions as causes into your own exception. 一种解决方案是创建自己的更通用的异常类,该类将扩展Exception并将未处理的异常作为原因包装到您自己的异常中。 This way you can at least reduce some exceptions from methods signatures. 这样,您至少可以减少方法签名中的某些异常。 example: 例:

Create new class StartupException or ConfigurationException and throw it with the main exception after catching it as cause during startup phase. 创建新类StartupExceptionConfigurationException并在启动阶段将其捕获为原因后将其与主要异常一起抛出。

Moreover if you would make StartupException extends RuntimeException) you would not have to declare such exception. 此外,如果您要使StartupException extends RuntimeException) ,则不必声明此类异常。

Another way would be to wrap everything into RuntimeException 另一种方法是将所有内容包装到RuntimeException

If abowe does not suit your needs than this is probably design flaw, (if you really cannot handle it) that you will have to deal with it. 如果abowe不适合您的需求,那么这可能是设计缺陷(如果您确实无法解决),则必须对其进行处理。

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

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