在我的自定义异常类中,我已覆盖toString():
@Override
public String toString() {
final String msg = getLocalizedMessage();
// base
String str = getClass().getName() + ": [" + code + "]";
// message
if (msg != null)
str += " " + msg;
// extra
if (extra != null) {
str += '\n' + extra.toString();
}
return str;
}
Run Code Online (Sandbox Code Playgroud)
(是的,我知道我应该StringBuilder在那里使用)
但是,当我记录这样的异常(via org.slf4j.Logger.warn(String msg, Throwable err))时,输出与vanilla异常一样:
webersg.util.service.ServiceError: null
at webersg.util.service.ServiceTools.decodeException(ServiceTools.java:39) ~[bin/:na]
at tr.silvercar.rummikub.robot.LobbyConnection.sendRequestTo(LobbyConnection.java:143) ~[bin/:na]
at tr.silvercar.rummikub.robot.LobbyConnection.sendRequest(LobbyConnection.java:98) ~[bin/:na]
at tr.silvercar.rummikub.robot.Robot.<init>(Robot.java:32) ~[bin/:na]
at tr.silvercar.rummikub.robot.RobotController.start(RobotController.java:81) ~[bin/:na] …Run Code Online (Sandbox Code Playgroud) 当Exception发生时,您可以打印出StackTrace并查看它.
如果你想在没有异常的情况下获得StackTrace怎么办?
有没有办法做到这一点?
我正在编写一些可以在堆栈中生成Exceptions的代码,并且我有一个靠近顶层的层,它捕获这些异常并将它们发送出去以供错误处理模块处理.我想要的是错误处理模块能够将堆栈跟踪打印到其错误日志中,但我发现很难弄清楚这样做的方法是什么.
关于背景的一些注意事项:
代码是多线程的,所以我不确定sys.last_traceback的行为
我已经尝试在异常本身的构造函数中捕获堆栈.在这种情况下,sys.last_traceback有时是None(因为它只存在于未处理的异常情况下),并且并不总是正确的.我目前正在玩弄使用
self.stack = traceback.format_stack()[: - 2]
在异常的构造函数中,虽然这在信息方面看起来很有前景,但它并不像是"正确"的方式来做到这一点
我能够找到的所有如何执行此操作的示例都显示了如何在except块中打印堆栈跟踪,而不是在以后的错误处理模块中打印,这似乎与我想要的行为不同.(例如,参见Python代码中的方法打印当前调用堆栈)
我已经在python docs(http://docs.python.org/library/traceback.html)中挖掘了traceback模块,并且无法弄清楚这是否符合我的要求.它似乎主要关注格式化回溯,因为您可能从sys.last_traceback检索.它有一些使用示例,但没有一个与我正在尝试做的事情相符.
我不相信我是第一个想要这样做的人,所以我必须遗漏一些东西.任何正确方向的指针都非常赞赏.
我的客户有一个错误,当我查看日志时我们跟踪异常,一些堆栈跟踪没有行号:
at xxxx.xxx.xx.x.xx.DayIntervalRule.getInterval(DayIntervalRule.java)
at xxxx.xxx.xx.x.xx.XXSchedule.getNextDueDate(XXSchedule.java)
at xxxx.xxx.xx.x.xx.XXSchedule.evaluateRules(XXSchedule.java)
Run Code Online (Sandbox Code Playgroud)
请注意:我已将包名替换为类似"xx"的内容,并且我们的应用程序中定义了所有类和方法:
完整堆栈跟踪如下:
java.lang.NullPointerException
at xxxx.xxx.xx.x.xx.DayIntervalRule.getInterval(DayIntervalRule.java)
at xxxx.xxx.xx.x.xx.XXSchedule.getNextDueDate(XXSchedule.java)
at xxxx.xxx.xx.x.xx.XXSchedule.evaluateRules(XXSchedule.java)
at xxxx.xxx.xx.x.xx.EvaluateRulesVistor.visitXXNode(EvaluateRulesVistor.java:56)
at xxxx.xxx.xx.x.xx.XXNode.accept(XXNode.java:396)
at xxxx.xxx.xx.x.xx.AssetXX.traverseForest(AssetXX.java:351)
at xxxx.xxx.xx.x.xx.AssetXX.run(AssetXX.java:70)
at xxxx.xxx.xx.x.xx.XXEngine.doForecast(XXEngine.java:437)
at xxxx.xxx.xx.x.xx.XXEngine.forecastWorkOrders2(XXEngine.java:380)
Run Code Online (Sandbox Code Playgroud)
我感兴趣的是为什么会发生这种情况?我的客户可能对现有代码(定制)做了些什么吗?
在下面的代码片段中,该printStackTrace()方法在catch block.中调用.运行程序后,您可以看到有时printStackTrace()连续几次运行而不是按printStackTrace()- > catch block- > 的顺序运行finally block.
如果您更改static boolean b为false然后按System.out.print(e)顺序执行.
那么为什么printStackTrace()表现方式不同呢?(带线程的东西??)
public class PrintStackTrace {
static boolean b = true;
public static void main(String[] args){
for(int i = 0; i < 100; i++){
try{
throw new Exception("[" + i + "]");
}
catch(Exception e){
if(b){
e.printStackTrace();
}
else{
System.out.print(e);
}
System.out.print(" Catch: " + i);
}
finally{
System.out.print(" Finally: " …Run Code Online (Sandbox Code Playgroud) 在我的junit 4测试代码中,我正在使用包含如下代码的测试规则:
catch (Throwable t) {
t.printStackTrace();
throw t;
}
Run Code Online (Sandbox Code Playgroud)
Findbugs对此有所抱怨,这是正确的-我们的生产代码中不应这样做。但是,在这种情况下,我认为用法是合理的,我尝试使用@SuppressFBWarnings注释使findbugs静音。但是,两者都没有
@SuppressFBWarnings
private void warmUp() throws Throwable {
Run Code Online (Sandbox Code Playgroud)
也不
@SuppressFBWarnings("IMC_IMMATURE_CLASS_PRINTSTACKTRACE")
private void warmUp() throws Throwable {
Run Code Online (Sandbox Code Playgroud)
也不
@SuppressFBWarnings({"IMC_IMMATURE_CLASS_PRINTSTACKTRACE"})
private void warmUp() throws Throwable {
Run Code Online (Sandbox Code Playgroud)
有理想的结果。
如何正确使用@SuppressFBWarnings取消警告?
我有类似的东西.
void func() {
try {
//socket disconnects in middle of ..parsing packet..
} catch(Exception ex) {
if(!ex.getMessage().toString().equals("timeout") || !ex.getMessage().toString().equals("Connection reset")) {
debug("Exception (run): " + ex.getMessage());
ex.printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud)
为什么当我得到连接重置异常或超时异常时,它仍然在条件内.我尝试没有toString,没有运气.
我需要将异常记录到数据库中.数据库API声明我可以将值作为ByteBuffer传递或作为byte []数组传递.哪个更有效率?
private final static byte[] getThrowableStackTraceBytes(Throwable throwable) {
StringWriter throwableStackTraceStringWriter = new StringWriter();
throwable.printStackTrace(new PrintWriter(throwableStackTraceStringWriter));
return throwableStackTraceStringWriter.toString().getBytes();
}
Run Code Online (Sandbox Code Playgroud)
与
private final static ByteBuffer getThrowableStackTraceByteBuffer(Throwable throwable) {
ByteArrayOutputStream throwableStackTraceByteArrayOutputStream = new ByteArrayOutputStream();
throwable.printStackTrace(new PrintStream(throwableStackTraceByteArrayOutputStream));
ByteBuffer throwableByteBuffer = ByteBuffer.wrap(throwableStackTraceByteArrayOutputStream.toByteArray());
return throwableByteBuffer;
}
Run Code Online (Sandbox Code Playgroud)
我认为如果我使用ByteBuffer,整体操作会更有效,特别是在它被传递到数据库方法后处理它时.我对吗?
(具体来说,我需要将异常记录到Hypertable中,它使用Thrift Java API.)
所以,我有这个类,我想打印调用哪些方法.当我运行它时,它只打印trace和main,但不打印method1和method2.如何更改它以便打印method1和method2,从main调用的方法?
public class SomeClass
{
public void method1() {}
public void method2() {}
public static void main(String args[]) throws Throwable
{
SomeClass c = new SomeClass();
c.method1();
c.method2();
SomeClass.trace();
}
public static void trace() throws Throwable
{
Throwable t = new Throwable();
StackTraceElement[] stack = t.getStackTrace();
for(StackTraceElement s : stack)
System.out.println(s.getMethodName());
}
}
Run Code Online (Sandbox Code Playgroud) 每当我们尝试使用printStackTrace()方法打印堆栈跟踪时,为什么输出不按预期顺序?假设我们有一些打印语句,并且printStackTrace()输出不按预期顺序。
public class Main {
public static void main(String[] args) {
Main m = new Main();
m.test1();
System.out.println("main method");
}
public void test1() {
System.out.println(test2());
System.out.println("test1");
}
public int test2() {
try {
throw new Exception();
} catch (Exception e) {
System.out.println("exception");
e.printStackTrace();
} finally {
}
return 2;
}
Run Code Online (Sandbox Code Playgroud)
}
预期输出应该是:
exception
java.lang.Exception
at com.infor.jdbc.Main.test2(Main.java:18)
at com.infor.jdbc.Main.test1(Main.java:12)
at com.infor.jdbc.Main.main(Main.java:7)
2
test1
main method
Run Code Online (Sandbox Code Playgroud)
但实际结果是:
exception
java.lang.Exception //from printStackTrace
2
test1
main method
at com.infor.jdbc.Main.test2(Main.java:18) //from …Run Code Online (Sandbox Code Playgroud) printstacktrace ×10
java ×8
stack-trace ×5
exception ×3
bytearray ×1
bytebuffer ×1
c# ×1
debugging ×1
findbugs ×1
logback ×1
python ×1
slf4j ×1
string ×1
throwable ×1