Pregunta

Para depurar solicitudes fallidas, me gustaría imprimir toda la información proveniente de HttpServletRequest.

Ahora, es posible que una solicitud falle parcialmente (por ej.Varias coincidencias tienen éxito, pero una falló), en cuyo caso me gustaría detectar la excepción en el método interno que falló, imprimir el error + ServletUtil.toStringHttpServletRequest() y continuar brindando el servicio (degradado pero aún útil vs.falla completa de la solicitud).

Nuestra implementación actual detecta la excepción e imprime información tonta ("getRules falló") o lanza la excepción hasta doGet() (cancelando efectivamente el servicio para el usuario), mientras que en doGet() tengo acceso a HttpServletRequest donde puedo imprimir en la información de depuración relevante (encabezados, parámetros...).

Pasar HttpServletRequest a cada función llamada durante la solicitud que podría fallar parece un poco feo, lo haré si no aparece otra solución elegante.

Crear un encabezado anterior ServletUtil.toStringHttpServletRequest() y almacenarlo en un mapa ThreadLocal sería un desperdicio tanto de memoria como de tiempo de CPU.Por alguna razón, parece incorrecto almacenar el objeto HttpServletRequest en ThreadLocal (corríjalo si me equivoco).

La información de depuración se escribe en el registro de la máquina local y se envía por correo electrónico directamente a los desarrolladores (Excelente trabajo log4j TLSSMTPAppender), por lo que iniciar sesión en varios lugares no será práctico (será necesario reunir varios correos electrónicos para comprender qué está pasando) y acceder al servidor mediante ssh es algo antiguo :) (Estamos todos nublados aquí...Es posible que el servidor no exista cuando pueda ver el error)

Entonces, mi solución es obtener acceso a "PrintErrorUtility" (TODO:mejor nómbralo).Eso recibirá (String errorMsg, Throwable t, HttpServletRequest) que imprimirá el error junto con toda la información relevante...Esto se llamará desde bloques internos try {} catch que notificarán sobre el error pero no cancelarán la solicitud por este motivo.

Obviamente me refiero a servidores que se ejecutan en producción.

¿Comentarios?Por favor avise.

Gracias, Máximo.

¿Fue útil?

Solución

Haga esta tarea en un Filter después el FilterChain#doFilter() llamar.El ServletRequest El objeto ya está allí.En el código comercial donde esta excepción se suprimirá correctamente, almacene la excepción como un atributo de solicitud y simplemente deje que Filter compruébalo/obténgalo de la solicitud.


Actualizar:Según los comentarios, aquí hay un ejemplo:

public class Context { 
    private static ThreadLocal<Context> instance = new ThreadLocal<Context>();
    private HttpServletRequest request;
    private List<Exception> exceptions = new ArrayList<Exception>();

    private Context(HttpServletRequest request) {
        this.request = request;
        this.request.setAttribute("exceptions", exceptions);
    }

    public static Context getCurrentInstance() {
        return instance.get();
    }

    public static Context newInstance(HttpServletRequest request) {
        Context context = new Context(request);
        instance.set(context);
        return context;
    }

    public void release() {
        instance.remove();
    }

    public void addException(Exception exception) {
        exceptions.add(exception);
    }
}

Y aquí se explica cómo usarlo en el servlet de su controlador:

Context context = Context.newInstance(request);
try {
    executeBusinessCode();
} finally {
    context.release();
}

Y así es como podría usarlo en el código comercial ejecutado:

} catch (Exception e) {
    Context.getCurrentInstance().addException(e);
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top