use of com.peterphi.std.guice.restclient.exception.RestException in project stdlib by petergeneric.
the class RemoteExceptionClientResponseFilter method filter.
@Override
public void filter(final ClientRequestContext requestContext, final ClientResponseContext responseContext) throws IOException {
final int code = responseContext.getStatus();
String operationId;
if (Tracing.isVerbose()) {
operationId = requestContext.getHeaderString(TracingConstants.HTTP_HEADER_CORRELATION_ID);
if (operationId != null)
Tracing.logOngoing(operationId, "HTTP:resp", () -> "" + code);
else
// can't find outgoing trace id
operationId = Tracing.log("HTTP:resp:unexpected", () -> "" + code);
} else {
operationId = null;
}
if (code >= 200 && code <= 299)
// Do not run if the return code is 2xx
return;
if (responseContext.getHeaders().containsKey(RestThrowableConstants.HEADER_RICH_EXCEPTION)) {
try {
final InputStream is = responseContext.getEntityStream();
RestFailure failure;
if (tryParseLegacyExceptionNamespace) {
// If parsing the legacy namespace fails, throw the original parse error back to the client
try {
// Mark the start of the stream so we can reset back to it if we need to process this as a legacy exception
is.mark(Integer.MAX_VALUE);
failure = parseResponse(is);
} catch (JAXBUnmarshalException e) {
log.trace("Error parsing rich exception response, will fall back on parsing it as a legacy exception XML", e);
try {
failure = parseLegacyResponse(is);
} catch (Throwable legacyFailure) {
log.trace("Error parsing rich exception response as legacy rich exception XML!", legacyFailure);
// throw the original exception
throw e;
}
}
} else {
failure = parseResponse(is);
}
if (Tracing.isVerbose() && failure != null && failure.exception != null) {
final ExceptionInfo ei = failure.exception;
Tracing.logOngoing(operationId, "HTTP:error", () -> ei.shortName + " " + ei.detail);
}
RestException exception = exceptionFactory.build(failure, responseContext);
// Try to shorten the stack trace
exception.fillInStackTrace();
throw exception;
} catch (ResponseProcessingException e) {
throw e;
} catch (Throwable e) {
throw new ResponseProcessingException(null, "Error mapping exception from thrown from " + requestContext.getUri() + " to exception!", e);
}
}
}
use of com.peterphi.std.guice.restclient.exception.RestException in project stdlib by petergeneric.
the class RedirectToOAuthAccessRefuser method refuse.
@Override
public Throwable refuse(final AuthScope scope, final AuthConstraint constraint, final CurrentUser login) {
final RestException accessDeniedException = new RestException(403, "You do not have sufficient privileges to access this resource" + (constraint != null ? ": " + constraint.comment() : "") + ". Required role: " + scope.getRole(constraint) + ". You are: anonymous=" + login.isAnonymous() + ", browser=" + isBrowserConsumer());
// If the user is logged in, deny access with a 403
if (!login.isAnonymous()) {
throw accessDeniedException;
} else if (!isBrowserConsumer()) {
// Non-browser consumer, send back an HTTP 401 immediately
// TODO allow configuration of Basic with a realm?
Response tryBasicAuth = Response.status(401).header("WWW-Authenticate", "Bearer").build();
throw new LiteralRestResponseException(tryBasicAuth, accessDeniedException);
} else if (!isGETRequest()) {
// Don't redirect requests other than GET (the browser will retry the POST/PUT/DELETE/etc. against the redirect endpoint!
throw new RestException(401, "You must log in to access this resource! Could not redirect you to the login provider because you were submitting a form, not requesting a page. Please return to the main page of the application and proceed to log in", accessDeniedException);
} else {
// Start an authorisation flow with the OAuth2 provider
final OAuth2SessionRef sessionRef = sessionRefProvider.get();
final URI redirectTo = sessionRef.getAuthFlowStartEndpoint(getRequestURI(), null);
throw new LiteralRestResponseException(Response.seeOther(redirectTo).build(), accessDeniedException);
}
}
use of com.peterphi.std.guice.restclient.exception.RestException in project stdlib by petergeneric.
the class ServiceManagerResourceUIServiceImpl method getResource.
/**
* N.B. transaction may be read-write because this read operation may result in reading a new template (or discovering an
* update was made to the template)
*
* @param id
*
* @return
*/
@Override
@Transactional
public String getResource(String id) {
final TemplateCall call = templater.template("resource_template");
final ResourceTemplateEntity entity = resourceProvisionService.getOrCreateTemplate(id);
if (entity == null)
throw new RestException(404, "No such resource with id: " + id);
call.set("entity", entity);
call.set("nonce", nonceStore.getValue());
return call.process();
}
use of com.peterphi.std.guice.restclient.exception.RestException in project stdlib by petergeneric.
the class RestFailureMarshaller method renderFailure.
/**
* Render a Throwable as a RestFailure
*
* @param e
*
* @return
*/
public RestFailure renderFailure(Throwable e) {
// Strip away ApplicationException wrappers
if (e.getCause() != null && (e instanceof ApplicationException)) {
return renderFailure(e.getCause());
}
RestFailure failure = new RestFailure();
failure.id = getOrGenerateFailureId();
failure.date = new Date();
if (e instanceof RestException) {
RestException re = (RestException) e;
failure.httpCode = re.getHttpCode();
failure.exception = renderThrowable(e);
} else {
// by default
failure.httpCode = 500;
failure.exception = renderThrowable(e);
}
return failure;
}
use of com.peterphi.std.guice.restclient.exception.RestException in project stdlib by petergeneric.
the class ServiceManagerResourceUIServiceImpl method doProvision.
@Override
public Response doProvision(final String id, final String nonce) {
nonceStore.validate(nonce);
final ResourceTemplateEntity entity = resourceProvisionService.getOrCreateTemplate(id);
if (entity == null)
throw new RestException(404, "No such resource with id: " + id);
resourceProvisionService.newInstance(id, Collections.emptyMap());
// Redirect to template page
return Response.seeOther(URI.create("/resources/template/" + id)).build();
}
Aggregations