@Override public Object wrap(final Req req, final HandlerInvocation invocation) { final AtomicReference<Object> resultHolder = new AtomicReference<>(); U.must(txMode != null && txMode != TransactionMode.NONE); boolean readOnly = (txMode == TransactionMode.AUTO) ? HttpUtils.isGetReq(req) : txMode == TransactionMode.READ_ONLY; try { JPA.transaction(() -> { Object res = invocation.invokeAndTransformResultCatchingErrors(result -> { if (result instanceof Throwable) { return result; } // serialize the result into a HTTP response body, while still inside tx (see #153) RespBody body = BodyRenderer.resultToRespBody(req.response(), result); return body; }); if (res instanceof Throwable) { // throw to rollback Throwable err = (Throwable) res; throw U.rte("Error occurred inside the transactional web handler!", err); } else { resultHolder.set(res); } }, readOnly); } catch (Throwable e) { resultHolder.set(e); } return resultHolder.get(); }
private static RespBody createRespBodyFromResult(Req req, RespImpl resp) { Object result = resp.result(); Object body = resp.body(); if (result instanceof RespBody) { return (RespBody) result; } else if (body instanceof RespBody) { return (RespBody) body; } else if (resp.mvc()) { byte[] bytes = ResponseRenderer.renderMvc((ReqImpl) req, resp); HttpUtils.postProcessResponse(resp); // the response might have been changed, so post-process again return new RespBodyBytes(bytes); } else if (body != null) { return new RespBodyBytes(Msc.toBytes(body)); } else if (result != null) { return resultToRespBody(resp, result); } else { throw U.rte("There's nothing to render!"); } }
private static RespBody createRespBodyFromResult(Req req, RespImpl resp) { Object result = resp.result(); Object body = resp.body(); if (result instanceof RespBody) { return (RespBody) result; } else if (body instanceof RespBody) { return (RespBody) body; } else if (resp.mvc()) { byte[] bytes = ResponseRenderer.renderMvc((ReqImpl) req, resp); HttpUtils.postProcessResponse(resp); // the response might have been changed, so post-process again return new RespBodyBytes(bytes); } else if (body != null) { return new RespBodyBytes(Msc.toBytes(body)); } else if (result != null) { return resultToRespBody(resp, result); } else { throw U.rte("There's nothing to render!"); } }