【问题标题】:Throwing and logging Exceptions, a better way抛出和记录异常,更好的方法
【发布时间】:2012-04-30 16:53:34
【问题描述】:

最后,我想

if (badThingsHappen) {
 log the issue
 throw exception with description
}

这里明显的冗余是异常描述和要记录的消息通常是相同的。

这看起来不必要的冗长

if (badThingsHappen) {
 logger.error("oh no! not again!");
 throw new AppException("oh no! not again!");
}

声明临时字符串感觉不对

if (badThingsHappen) {
 String m = "oh no! not again!";
 logger.error(m);
 throw new AppException(m);
}

是否可以让 Exception 的构造函数处理日志记录?有没有更好(更清洁)的方法?

【问题讨论】:

  • 我认为您不需要在异常之前记录语句,您可以在自定义异常或通用异常中定义消息
  • 假设您的异常被调用类捕获(希望是这种情况),大多数时候,您不想记录并重新抛出,因为调用类可能也会记录。
  • @assylias 我明白你的意思.. 就本程序而言,我想在问题发生时立即记录。但我明白你的意思
  • 我同意 assylias,记录异常算作“处理”异常。它应该由优雅地处理它的 catch 语句来完成。

标签: java error-handling


【解决方案1】:

您可以使用实用方法:

public class AppException extends Exception {
    public static AppException logAndThrow(Logger logger, String message) throws AppException {
        AppException e = new AppException(message);
        // log the stack trace as well
        logger.error(message, e);
        throw e;
    }
}

并使用它:

if (badThingsHappen) {
    AppException.logAndThrow(logger, "oh no! not again!");
}

【讨论】:

    【解决方案2】:

    我通常更喜欢在捕获异常时记录它们,而不是在抛出异常时记录它们。

    这会更多地清理日志,并让“客户端”代码更精确地处理异常和信息输出,因为您希望在记录时与异常关联的信息可能取决于上下文。

    如果您确实想在它发生时立即记录,我会构建异常并在抛出之前记录它,例如:

    if(badthingshappen){
        Exception e = new Exception("holy $%##");
        logger.log(e);
        throw e;
    }
    

    有点冗长是的...但是这个 java.

    【讨论】:

      【解决方案3】:

      通常在处理异常和日志记录要求时,我会在异常中包含日志记录支持。

      异常通常继承自我们项目中的 Base Exception 类,它具有用于记录 log4j 或其他记录实用程序的挂钩。

      class Problem extends java.lang.Exception {
        private boolean debug=false;
        public Problem(String message) {
          if(debug) {
            logging.exception(message);
            /* Maybe a stack trace? */
          }
        }
      }
      

      【讨论】:

      • 取决于应用程序,我们在第一次迭代中使用它,但后来因为我们开始依赖异常来报告小问题(糟糕的设计)但我们的 CORE Exceptions 仍然记录,其他异常没有t 记录,因为当它是一个大型应用程序时,您会受到性能影响。
      • 我喜欢这种模式的一点是,您可以选择(调试)来决定是否记录异常。
      【解决方案4】:

      我今天自己写了一个错误记录方法(这个是用来记录错误,如果它们发生在监听器方法中,所以它也记录了发生错误的方法和实现监听器的对象)帮助跟踪):

      protected void listenerError(String listenerMethodName, Object listener,
              RuntimeException e) {
          logger.error("Exception while calling " + listenerMethodName
                  + " on object " + listener, e);
          throw e;
      
      }
      

      我在有问题的类(或者确切地说是基类)中编写了它,因为您可能想在该类(以及所有子类)中使用记录器。另一种选择是在实用程序类中创建实用程序方法(我不会为它编写异常类),并提供记录器作为参数:

      class ExceptionUtil {
      
        public static error(Exception e, Logger logger) {
           logger.error(e);
           throw e;
        }
      }
      

      当然,您可以根据需要提供方法和对象作为此方法(或其重载版本)的参数。

      【讨论】:

        猜你喜欢
        • 2012-02-12
        • 2016-05-30
        • 2014-04-27
        • 1970-01-01
        • 2014-03-31
        • 1970-01-01
        • 1970-01-01
        • 2014-10-20
        • 1970-01-01
        相关资源
        最近更新 更多