App Engine推送队列的错误处理程序

时间:2015-03-04 12:17:18

标签: java google-app-engine servlets

我使用错误处理程序来获取有关App Engine应用程序中每个错误的通知。它适用于Cloud Endpoints和servlet,但我无法弄清楚如何处理推送队列调用的servlet中的错误。

web.xml

中的配置
<error-page>
    <exception-type>java.lang.Exception</exception-type>
    <location>/admin/error-notification</location>
</error-page>

我想要实现的场景

  • 将新任务添加到推送队列
  • 任务失败并重试x次(<task-retry-limit>x</task-retry-limit>
  • 一旦达到重试限制,任务就会从队列中删除,但是使用上次不成功运行的堆栈跟踪调用错误处理程序

问题是一旦删除任务,就不会调用任何内容。有没有办法像我上面描述的那样配置它?我不希望收到有关每个故障的通知,只是在从推送队列中删除任务之前的最后一次故障。

1 个答案:

答案 0 :(得分:0)

基于@ tx802的答案提示使用X-AppEngine-TaskRetryCount

如果没有在之前的运行中抛出异常,就不会重试任务,所以这是基于一个简单的hack来标记一些异常被抑制。在自定义错误处理程序中,您必须检查异常是否为SuppressedException的类型。如果它被抑制,您可以安全地跳过此异常,这意味着该任务将很快被重试。如果异常未包含在SuppressedException中,则表示已达到重试限制,这是应以某种方式处理的最终异常。

public abstract class PushQueueHttpServlet extends HttpServlet {

    @Override
    protected final void doGet(HttpServletRequest req, HttpServletResponse res) throws
            IOException, ServletException {
        try {
            doGet2(req, res);
        } catch (Throwable throwable) {
            String retryCountString = req.getHeader("X-AppEngine-TaskRetryCount");

            int retryCount;
            try {
                retryCount = Integer.parseInt(retryCountString);
            } catch (NumberFormatException e) {
                // Probably running outside of the task queue
                throw throwable;
            }

            if (retryCount == getTaskRetryLimit()) {
                throw throwable;
            } else {
                throw new SuppressedException(throwable);
            }
        }
    }

    protected abstract void doGet2(HttpServletRequest req, HttpServletResponse res) throws
            IOException, ServletException;

    protected abstract int getTaskRetryLimit();
}

SuppressedException上课

public class SuppressedException extends IOException {

    public SuppressedException(Throwable cause) {
        super(cause);
    }
}