@Override public byte[] bytes() throws IOException { throw new Err(Status.BAD_REQUEST); }
/** * Setup a custom error handler.The error handler will be executed if the current exception is an * instance of given type type. * * All headers are reset while generating the error response. * * @param type Exception type. The error handler will be executed if the current exception is an * instance of this type. * @param handler A route error handler. * @return This router. */ @Nonnull default Router err(final Class<? extends Throwable> type, final Err.Handler handler) { return err((req, rsp, x) -> { if (type.isInstance(x) || type.isInstance(x.getCause())) { handler.handle(req, rsp, x); } }); }
/** * Creates a new {@link Err}. * * @param status A HTTP status. Required. * @param message A error message. Required. * @param cause The cause of the problem. */ public Err(final int status, final String message, final Throwable cause) { super(message("", status, message), cause); this.status = status; }
public Status apply(final Throwable cause) { if (cause instanceof Err) { return Status.valueOf(((Err) cause).statusCode()); } /** * usually a class name, except for inner classes where '$' is replaced it by '.' */ Function<Class<?>, String> name = type -> Optional.ofNullable(type.getDeclaringClass()) .map(dc -> new StringBuilder(dc.getName()) .append('.') .append(type.getSimpleName()) .toString()) .orElse(type.getName()); Config err = conf.getConfig("err"); int status = -1; Class<?> type = cause.getClass(); while (type != Throwable.class && status == -1) { String classname = name.apply(type); if (err.hasPath(classname)) { status = err.getInt(classname); } else { type = type.getSuperclass(); } } return status == -1 ? Status.SERVER_ERROR : Status.valueOf(status); } }
/** * Produces a friendly view of the err, resulting map has these attributes: * * <pre> * message: exception message (if present) * status: status code * reason: a status code reason * </pre> * * @return A lightweight view of the err. */ public Map<String, Object> toMap() { return toMap(false); }
/** * Setup a route error handler. The error handler will be executed if current status code matches * the one provided. * * All headers are reset while generating the error response. * * @param statusCode The status code to match. * @param handler A route error handler. * @return This router. */ @Nonnull default Router err(final int statusCode, final Err.Handler handler) { return err((req, rsp, x) -> { if (statusCode == x.statusCode()) { handler.handle(req, rsp, x); } }); }
@Override public void handle(final Request req, final Response rsp, final Err ex) throws Throwable { log.error("execution of: {}{} resulted in exception\nRoute:\n{}\n\nStacktrace:", req.method(), req.path(), req.route().print(6), ex); Config conf = req.require(Config.class); boolean stackstrace = Try.apply(() -> conf.getBoolean("err.stacktrace")) .orElse(req.require(Env.class).name().equals("dev")); rsp.send( Results .when(MediaType.html, () -> Results.html(VIEW).put("err", ex.toMap(stackstrace))) .when(MediaType.all, () -> ex.toMap(stackstrace))); }
@Override public String text() throws IOException { throw new Err(Status.BAD_REQUEST); }
/** * Produces a friendly view of the err, resulting map has these attributes: * * <pre> * message: exception message (if present) * stacktrace: array with the stacktrace * status: status code * reason: a status code reason * </pre> * * @param stacktrace True for adding stacktrace. * @return A lightweight view of the err. */ public Map<String, Object> toMap(boolean stacktrace) { Status status = Status.valueOf(this.status); Throwable cause = Optional.ofNullable(getCause()).orElse(this); String message = Optional.ofNullable(cause.getMessage()).orElse(status.reason()); Map<String, Object> err = new LinkedHashMap<>(); err.put("message", message); if (stacktrace) { err.put("stacktrace", Throwables.getStackTraceAsString(cause).replace("\r", "").split("\\n")); } err.put("status", status.value()); err.put("reason", status.reason()); return err; }
/** * Creates a new {@link Err}. * * @param status A HTTP status. Required. * @param cause The cause of the problem. */ public Err(final Status status, final Throwable cause) { super(message(status, null), cause); this.status = status.value(); }
/** * Setup a route error handler. The error handler will be executed if current status code matches * the one provided. * * All headers are reset while generating the error response. * * @param predicate Apply the error handler if the predicate evaluates to <code>true</code>. * @param handler A route error handler. * @return This router. */ @Nonnull default Router err(final Predicate<Status> predicate, final Err.Handler handler) { return err((req, rsp, err) -> { if (predicate.test(Status.valueOf(err.statusCode()))) { handler.handle(req, rsp, err); } }); }
/** * Produces a friendly view of the err, resulting map has these attributes: * * <pre> * message: exception message (if present) * status: status code * reason: a status code reason * </pre> * * @return A lightweight view of the err. */ public Map<String, Object> toMap() { return toMap(false); }
@Override public void writeTo(final OutputStream output) throws Exception { throw new Err(Status.BAD_REQUEST); }
Throwable cause = Optional.ofNullable(err.getCause()).orElse(err);
/** * Creates a new {@link Err}. * * @param status A HTTP status. Required. * @param message A error message. Required. * @param cause The cause of the problem. */ public Err(final Status status, final String message, final Throwable cause) { super(message(status, message), cause); this.status = status.value(); }
/** * Setup a route error handler. The error handler will be executed if current status code matches * the one provided. * * All headers are reset while generating the error response. * * @param code The status code to match. * @param handler A route error handler. * @return This router. */ @Nonnull default Router err(final Status code, final Err.Handler handler) { return err((req, rsp, x) -> { if (code.value() == x.statusCode()) { handler.handle(req, rsp, x); } }); }
@Override public void handle(final Request req, final Response rsp, final Err ex) throws Throwable { log.error("execution of: {}{} resulted in exception\nRoute:\n{}\n\nStacktrace:", req.method(), req.path(), req.route().print(6), ex); Config conf = req.require(Config.class); boolean stackstrace = Try.apply(() -> conf.getBoolean("err.stacktrace")) .orElse(req.require(Env.class).name().equals("dev")); rsp.send( Results .when(MediaType.html, () -> Results.html(VIEW).put("err", ex.toMap(stackstrace))) .when(MediaType.all, () -> ex.toMap(stackstrace))); }
private Err typeError(final Class<?> type) { return new Err(Status.BAD_REQUEST, "Can't convert to " + ByteBuffer.class.getName() + " to " + type); } }
/** * Setup a custom error handler.The error handler will be executed if the current exception is an * instance of given type type. * * All headers are reset while generating the error response. * * @param type Exception type. The error handler will be executed if the current exception is an * instance of this type. * @param handler A route error handler. * @return This router. */ @Nonnull default Router err(final Class<? extends Throwable> type, final Err.Handler handler) { return err((req, rsp, x) -> { if (type.isInstance(x) || type.isInstance(x.getCause())) { handler.handle(req, rsp, x); } }); }
/** * Creates a new {@link Err}. * * @param status A HTTP status. Required. */ public Err(final Status status) { super(message(status, null)); this.status = status.value(); }