我最近惊讶地发现,此游戏框架控制器动作代码只有在例外后才被调用,但是当呼叫真正成功时,它从来没有被调用。
try {
InputStream is = getInputStreamMethod();
renderBinary(is, "out.zip");
catch (Exception e) {
e.printStackTrace();
} finally {
cleanUp();
}
也许该线程是终止的,或者当renderbinary()被调用时,但对我来说,这是非直觉的。我怀疑其他渲染()调用都会发生同样的事情,但我没有验证它。
我通过将renderbinary()移至尝试/捕获后解决了问题。进一步的调查显示,Play提供了@finally注释,以创建一种方法,该方法在控制器操作执行后将执行。警告是,在控制器中执行任何操作之后,这将被调用,因此它可能并不总是一个不错的选择。
我的问题是:为什么最终在renderbinary()之后未能执行该块,并且在任何地方都记录了这一点?我在剧本文档中找不到任何参考。
阐明导致此发现的事件的顺序:
本应由于最终块而被删除的文件。
认为这不可能是由非执行最终阻止引起的,我更改了使用Amazon SQS消息队列队列在最后块中发送消息的方法 - 单独的作业接收了消息并删除关联的文件。
没有发送消息。
我在代码中设置了断点,并确定renderbinary被调用,但最后块未被执行。
为了安全起见,我在最后的子句中添加了日志消息,这些消息也不存在。
我已经重复了多次调试练习,每次都没有执行最终子句。
(请注意,实际代码实际上并不像以上。这是一个非常简化的示例,只是为了说明情况。) 是真的。我今天刚刚发现了这一点,因为我的公司使用了 据我了解,这可能仅发生在2.0之前的 我不明白为什么或确切地完成此操作,但这显然是这种情况。 如果您发现特定的例外,我认为这不会发生。 但是,是的,您并不疯狂或不好的程序员。这确实只是一个怪异的,无证件的play
框架,有人遇到了它。play
版本中,但是当您在渲染呼叫后捕获所有异常时,play
显然会重写代码以跳过finally
块... play
Gotcha。