为什么 Action 报错不打印异常堆栈
Closed this issue · 8 comments
Mr-LiuDC commented
版本情况
JDK版本: JDK 1.8
hutool版本: 5.8.26
问题描述
我用SimpleServer
来实现简单的HTTP请求处理,为什么Action中报错了没打印任何堆栈异常信息?
- 复现代码
public class DemoAction implements Action {
private final Log log = Log.get();
@Override
public void doAction(HttpServerRequest request, HttpServerResponse response) {
int random = RandomUtil.randomInt(9);
if (random % 2 == 0) {
String msg = "Random number is even.";
log.info(msg);
response.write(msg);
} else {
String msg = "Random number is odd.";
log.error(msg);
throw new RuntimeException(msg);
}
}
}
![1714826763594](https://private-user-images.githubusercontent.com/18117854/327948581-45a010a8-2a50-40b3-8eec-95c227bf8cd5.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MTg1MjA4MTAsIm5iZiI6MTcxODUyMDUxMCwicGF0aCI6Ii8xODExNzg1NC8zMjc5NDg1ODEtNDVhMDEwYTgtMmE1MC00MGIzLThlZWMtOTVjMjI3YmY4Y2Q1LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA2MTYlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNjE2VDA2NDgzMFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTIyMGJhYWNkMzgzODI1OTYwNmJmODJlNWY0ZjNlYzQ4NGJkMmNhNzk5MDQ2YmYyNGRiMTk0ZTYwYzk1OWEyYzUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.wp-kBubkVPd3Fz4vyR73LAxtwIOQMRtINfws5CLqZLk)
looly commented
Hutool的log使用第三方Log框架,并根据引入包自动识别。
请检查第三方日志配置的info和error是否打开。
Mr-LiuDC commented
Hutool的log使用第三方Log框架,并根据引入包自动识别。
请检查第三方日志配置的info和error是否打开。
我截图里面是能够正常打印各个级别的日志,我问的是为什么没有异常堆栈信息,throw 的异常或者其他未捕获的未知异常都没有打印异常堆栈信息。
Mr-LiuDC commented
你说的传入 Exception 对象是没问题的,下面这行没有打印堆栈是什么问题呢?
throw new RuntimeException(msg);
Mr-LiuDC commented
我举个例子,我在 Action 里面用 DBUtil 进行数据库的读写操作,当报了异常,如果没有手动进行 catch 异常并手动打印异常,控制台居然没有打印任何异常信息。
looly commented
@Mr-LiuDC 终于明白你的意思了。
在Action中抛出异常是会被吃掉
的。
这个原因是 com. sun. net. httpserver
中HttpHandler
的创建处理机制并不抛出异常,此时需要你自定义com.sun.net.httpserver.Filter
或cn.hutool.http.server.filter.HttpFilter
/**
* 异常处理过滤器
*
* @author looly
*/
public abstract class ExceptionFilter implements HttpFilter {
@Override
public void doFilter(final HttpServerRequest req, final HttpServerResponse res, final Filter.Chain chain) {
try {
chain.doFilter(req.getHttpExchange());
} catch (final Throwable e) {
afterException(req, res, e);
}
}
/**
* 异常之后的处理逻辑
*
* @param req {@link HttpServerRequest}
* @param res {@link HttpServerResponse}
* @param e 异常
*/
public abstract void afterException(final HttpServerRequest req, final HttpServerResponse res, final Throwable e);
}
looly commented
这块6.x做的比较完善,5.8.8会增加ExceptionFilter
和DefaultExceptionFilter
。
这样有了异常会打印在页面中:
public class ExceptionServerTest {
public static void main(final String[] args) {
HttpUtil.createServer(8888)
.addFilter(new DefaultExceptionFilter())
.addAction("/", (req, res) -> {
throw new RuntimeException("Test Exception");
})
.start();
}
}