【问题标题】:write thrown exception to file将抛出的异常写入文件
【发布时间】:2012-01-30 22:22:13
【问题描述】:

是否可以在不使用 try catch 块的情况下将抛出的异常写入文件?

例如

public static void method() throws Exception, SQLException{
    if(Exception is thrown){
        write Exception to out.txt;
        write SQLException to out.txt;
    }
}

或者你必须这样做:

public static void method(){
    try{
        ...
    }catch(Exception ex){
        write ex to file;
    }catch(SQLException sqlex){
        write sqlex to file;
    }
}

【问题讨论】:

    标签: java exception exception-handling throws


    【解决方案1】:

    在 Java 中,我不认为这是可能的。

    但是,如果在 *nix 上执行,您可以只使用 redirect all output to a file(或者只是错误输出)。但这不是一个通用的解决方案。

    【讨论】:

      【解决方案2】:

      您必须以某种方式catch 该异常。如果你抓住它,然后决定写一个文件就可以了。鉴于您上面的内容,我建议使用第二种方法,因为 if 语句无法实际获取异常。

      【讨论】:

        【解决方案3】:

        在方法中捕获特定错误的唯一方法是使用 Try/Catch 块。但是,可以让一个类捕获所有未捕获的异常 - 即任何周围没有 Try/Catch 的异常。

        你可以编写一个自定义类来实现Java的UncaughtExceptionHandler接口。

        import java.lang.Thread.UncaughtExceptionHandler;
        
        public class CustomUncaughtExceptionHandler implements UncaughtExceptionHandler {
          public void uncaughtException(Thread thread, Throwable throwable) {
            /* Write to file here */
          }
        }
        

        然后您需要告诉 Java 虚拟机将未捕获的异常重定向到您的类。

        public static void main(String[] args){
          Thread.setDefaultUncaughtExceptionHandler(new CustomUncaughtExceptionHandler());
        }
        

        【讨论】:

        • 你应该小心这样做,因为你会破坏很多东西。
        • 我认为你不想使用这种方法。要访问此处理程序,您必须不捕获异常(如果您想尝试抛出任何异常,则所有异常都未捕获)。如果您既想将异常写入文件并处理异常情况,那您就很不走运了。
        【解决方案4】:

        除非您检测字节码(您可以使用代理和asm 之类的东西),否则您无法使用直接的 java 来执行此操作。您可以通过一个方面来做到这一点,这比字节码检测方法更容易。以aspectj 为例。一个方面可能是:

        public aspect ExceptionAdvice {
        
            pointcut allMethods() : execution(* *(..)) && !within(com.test.ExceptionAdvice);
        
            after() throwing(Exception e) : allMethods() {
                //write to a file or whatever - I'm lazy and just printed the stack
                e.printStackTrace ();
            }
        }
        

        一旦你将它编织到你的应用程序类中,所有抛出的异常都将通过这里的连接点。我刚刚打印了堆栈,但您可以将其记录到文件中或做任何您想做的事情。当连接点完成时,会继续抛出异常,以便调用代码有机会处理它。显然,您需要更改切入点定义以适合您的类,但这是一般的想法。

        【讨论】:

        • 你必须喜欢 AOP 才能处理这样的事情!
        【解决方案5】:

        没有。

        public static void method() throws Exception, SQLException{
            if(Exception is thrown){
                write Exception to out.txt;
                write SQLException to out.txt;
            }
        }
        

        异常从何而来?

        顺便说一句:您永远不会声明要抛出的最抽象的异常Exception。一些 RuntimeExceptions 几乎可以在任何地方发生(Nullpointer、OutOfMemory),因此在任何地方声明它们是没有用的。这只是噪音。

        public static void method() throws Exception, SQLException{
            try{
                ...
            }catch(Exception ex){
                write ex to file;
            }catch(SQLException sqlex){
                write sqlex to file;
            }
        }
        

        但如果你抓住了它,你通常不会抛出异常,因此根本不会声明抛出异常。

        【讨论】:

          【解决方案6】:

          在第二个块中你已经捕获了异常,所以不需要抛出异常,SqlException。

          在常规代码行中检测到异常,因此您不能为每个代码添加一个 if。是的,try/catch(write) 是唯一的方法。

          除非……你使用 if/else 代替异常处理

          【讨论】:

            【解决方案7】:

            您需要捕获异常并重新抛出它。

            public static void method() throws Exception, SQLException{
                try{
                    ...
                }
                catch(SQLException sqlex){
                    write sqlex to file;
                    throw ex;
                } 
                catch(Exception ex){
                    write ex to file;
                    throw ex;
                }
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2020-02-01
              • 1970-01-01
              • 2011-09-27
              • 1970-01-01
              • 2019-05-17
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多