【问题标题】:Customize Try/Catch code template based on exception基于异常自定义 Try/Catch 代码模板
【发布时间】:2012-07-03 08:04:40
【问题描述】:

有谁知道是否有办法根据异常在catch块中自动生成不同的代码?

Eclipse 函数 'Surround with try/catch' 生成一个 try/catch 块,其中仅包括转储堆栈跟踪。

我在代码中做了很多类似的事情,所以我的大多数异常都可能归结为三种左右不同的类型。我希望每个都有不同的 catch 块代码,并根据异常进行 eclipse 自动格式化。

例如: 如果我的代码生成 RemoteConnectionException 我想向用户显示一个对话框以重新连接。 如果它生成 RemoteContentException 我想记录它。

(这些都是我编的。)

提前致谢

更新: 我一直在四处寻找,有两种可能的解决方案。

1) 我发现了一个叫做快速代码插件的东西,它可以做我正在寻找的东西。 http://fast-code.sourceforge.net/index.htm

2) 对于专门处理异常,我可能只编写一个通用异常处理程序并修改 catch 块代码以将异常传递给它,而不是打印堆栈跟踪。然后 java 代码将根据异常类型确定要采取的操作。

【问题讨论】:

  • catch(RemoteConnectionException& exc) {if (handleRemoteConnectionException(exc) == false) throw;}

标签: java eclipse templates eclipse-templates


【解决方案1】:

模板有其局限性。但是,您的问题可以通过 Aspect 非常优雅地解决。 (http://www.eclipse.org/aspectj/) 只需为您需要的每种类型的“模板案例”创建一个新注释并使用环绕建议。

Ps:不要使用 printStackTrace() 来 syserr/sysout。有这么多生产级的轻量级日志框架....pleeeaseee...不要滥用可怜的小 System.out/err :)

编辑:

日志记录/基准测试建议的一些示例。 (注意:我将 spring AOP 用于切面,而 lombok 用于轻松访问日志框架。getCurrentUser() 代码在这里并不真正相关,它只是用于从 Spring Security 获取当前用户)

package com.XXXXXXXX.aspects;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

@Component
@Aspect
@Slf4j
public class LoggerAspect {

    private final static String DOMAIN = "XXXXXXXX";

    private static String getCurrentUser() {
        String username = "Unknown";
        try {
            Object principal = SecurityContextHolder.getContext().
                    getAuthentication().
                    getPrincipal();
            if (principal instanceof UserDetails) {
                username = ((UserDetails) principal).getUsername();
            } else {
                username = principal.toString();
            }
        } catch (Exception e) {
        }
        return username;
    }

    @Pointcut("within(com.XXXXXXXX.services..*)")
    public void inServiceLayer() {
    }

    @Pointcut("execution(* getMatcherInfo(..)) || execution(* resetCounter(..))")
    public void notToAdvise() {
    }

    @Around("com.XXXXXXXX.aspects.LoggerAspect.inServiceLayer() && !com.XXXXXXXX.aspects.LoggerAspect.notToAdvise()")
    public Object doLogging(ProceedingJoinPoint pjp)
            throws Throwable {
        long start = System.nanoTime();
        StringBuilder sb = new StringBuilder(DOMAIN);
        sb.append('/').
                append(getCurrentUser()).
                append(" accessing ").
                append(pjp.getSignature().
                getDeclaringTypeName()).
                append('.').
                append(pjp.getSignature().
                getName());
        log.trace("START: " + sb.toString());
        Object retVal = pjp.proceed(pjp.getArgs());
        long duration = System.nanoTime() - start;
        log.trace("STOP: " + duration / 1000000 + " msec. " + sb.toString());
        return retVal;
    }
}

【讨论】:

  • 摆脱那个愚蠢的打印堆栈跟踪正是我想要自定义模板的原因。 ^_^ 我从事运营工作已有十多年了,我对开发人员在应该处理异常时经常转储堆栈跟踪感到震惊。如果这是完全出乎意料的事情,我可以理解,但是您知道,例如,当您访问文件时。有一些预期的失败案例很容易处理。 ^_^
  • 什么是方面?方面4j?我正在查找,但我不确定您在说什么。
  • @user1497207:在答案中添加了方面链接
  • @GergelySzilagyi 你能详细说明如何在这里使用方面吗?哪个连接点应该有周围的建议?建议应该包含什么? (您能否在回复时标记我以便我收到通知?谢谢)
  • @MiserableVariable:完整的 Aspect-primer 不适合评论框,但我会尝试为您指出正确的方向。这个例子eclipse.org/aspectj/doc/released/progguide/… 几乎已经为当前的问题做好了准备,尽管它使用了单独的前后通知而不是周围的通知,但在这种情况下并不重要。
【解决方案2】:

我不确定eclipse中是否有这样的选项。我已经使用带有 try/catch 选项的环绕选项已经有一段时间了,它总是在异常 e 的 catch 块中转储默认的 e.printStackTrace() 行。

【讨论】:

  • 您可以更改模板,但不能使其特定于异常。我通常将它更改为给我编译错误的东西(所以我不得不添加一个 catch 块)
猜你喜欢
  • 2017-01-05
  • 2021-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-16
  • 2014-04-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多