【问题标题】:Java Not Catching ExceptionJava 未捕获异常
【发布时间】:2012-10-26 15:04:07
【问题描述】:

很遗憾,我无法控制 getUserByUserId(String)。它的行为方式是如果找到用户则返回一个用户,如果没有找到用户则抛出一个OntNoObjectExistsException。我的问题是,由于某种原因,当它被抛出时,catch 没有捕捉到OntNoObjectExistsException

此异常的类型层次结构是:OntNoObjectExistsException -> OntException -> Exception -> Throwable

public boolean isUserIdAvailable(String userId) {
    try {
        return super.getUserByUserId(userId) == null;
    } catch (OntNoObjectExistsException e){
        return true;
    } catch (Exception ex) {
        appLog.error(ex.getMessage());
    }
    return false;
}

我尝试了这段代码来试水,但问题仍然存在。请注意,我正在捕捉Throwable

public boolean isUserIdAvailable(String userId) {
    try {
        return super.getUserByUserId(userId) == null;
    } catch (Throwable ex) {
        appLog.error(ex.getMessage());
    }
    return false;
}

这是堆栈跟踪:

com.opennetwork.exception.OntNoObjectExistsException: User not found
    at com.bcbst.dsmart.api.WebUser.getUserByUserId(WebUser.java:411)
    at com.bcbst.dsmart.api.WebProspectiveMemberBean.isUserIdAvailable(WebProspectiveMemberBean.java:71)
    at com.bcbst.dsmart.api.EJSLocalStatelessWebProspectiveMember_ce00ef7b.isUserIdAvailable(EJSLocalStatelessWebProspectiveMember_ce00ef7b.java:120)
    at com.bcbst.prospectivememberweb.actions.UsageagreementAction.execute(UsageagreementAction.java:61)
    at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:484)
    at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:274)
    at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1482)
    at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:525)

另请注意,这是 java 1.4。还有一些我现在无法控制的事情。

【问题讨论】:

  • 您的 WebUser 类中导入的异常的完整包名是什么?
  • 检查你只有一个 OntNoObjectExistsException 并且它就是你正在捕获的那个。
  • FWIW,我尝试减少捕获 Throwable 的单个捕获,但问题仍然存在。
  • @dharga 这很重要,请确保您编辑您的问题以清楚地强调这一点。
  • 无论您的问题是什么,从您发布的代码中都看不出来。您是否检查了堆栈跟踪中的行号以确保它是从您认为的位置抛出的?

标签: java logging exception-handling stack-trace java1.4


【解决方案1】:

您正在抛出新的Throwable 的超类中捕获异常。

【讨论】:

  • 你能扩展一下这个答案吗?
  • @Duncan 解释什么,看一下抛出异常的stacktrace。它可能是 RuntimeException 从那里重新抛出或堆栈跟踪。
  • 我认为超类方法抛出异常毫无疑问。问题在于为什么 OP 无法捕获异常。您对 rethrown RuntimeException 的最后评论很有趣。
  • 这是来自 JavaDoc:A method is not required to declare in its throws clause any subclasses of RuntimeException that might be thrown during the execution of the method but not caught.
  • 它不是 RuntimeException 的子类。我发布了类型层次结构。
【解决方案2】:

我同意另一个答案,即使用异常进行流控制是非常糟糕的做法,但要实际回答您的问题,您是否尝试捕获 Throwable 而不是 Exception?

catch (Throwable t) {
    // handle here.
}

【讨论】:

  • 引用 OP:“FWIW,我尝试减少一个捕获 Throwable 的捕获,但问题仍然存在”
  • @Ben 作为评论可能会更好。
【解决方案3】:

让我提出一个假设。 WebUser.getUserByUserId 包含此代码:

if (userNotFoundCondition) {
  OntNoObjectExistsException e = new OntNoObjectExistsException("User not found");
  logger.error("User not found", e);
  throw e;
}

此假设与您提交的所有证据 100% 一致。为了继续你的调查,你必须首先反驳这个假设。

【讨论】:

  • 足够接近。抛出后,它被捕获,e.printStackTrace() 然后重新抛出。为了您的帮助,我选择了这个答案。
  • @dharga 如果它被重新抛出,它必须被子类代码捕获。
  • 这甚至超出了我的想象。写这篇文章的人显然不知道你可以实例化一个异常而不立即抛出它。
  • 我很清楚,但根本没有想到。因此,为什么我将您的解决方案归功于您,因为您是建议我想到它的人。
  • 不,我的意思是他为什么写try {throw new OntNoObjectExistsException();} catch (OntNoObjectExistsException e) { e.printStacktrace(); throw e;},而他本来可以简单地说OntNoObjectExistsException e = new OntNoObjectExistsException(); e.printStacktrace(); throw e;
【解决方案4】:

你无法控制getUserByUserId();但是,它似乎在同一个包com.bcbst.dsmart.api 中,所以这个答案假设(以便继续)它不在同一个项目中的责任范围内,但你有它的来源文件

getUserByUserId() 所属的类的源代码与运行时使用的编译版本是否不匹配?

如果 throws 语句在编译后在该类中被修改,或者异常本身已经改变,这可以解释你这种明显荒谬的情况。

有关该假设的更多信息,请参阅 SO 上的 this answer

=> 重新编译所有内容,然后重新部署。

【讨论】:

    猜你喜欢
    • 2010-11-25
    • 2015-07-04
    • 1970-01-01
    • 2014-03-22
    • 1970-01-01
    • 2010-09-28
    • 2012-05-31
    相关资源
    最近更新 更多