use of com.palantir.conjure.java.api.errors.RemoteException in project conjure-java-runtime by palantir.
the class RemoteExceptionResponseHandlerTest method extractsRemoteExceptionForAllErrorCodes.
@Test
public void extractsRemoteExceptionForAllErrorCodes() throws Exception {
for (int code : ImmutableList.of(300, 400, 404, 500)) {
RemoteException exception = decode(MediaType.APPLICATION_JSON, code, SERIALIZED_EXCEPTION).get();
assertThat(exception.getCause()).isNull();
assertThat(exception.getStatus()).isEqualTo(code);
assertThat(exception.getError().errorCode()).isEqualTo(ErrorType.FAILED_PRECONDITION.code().name());
assertThat(exception.getError().errorName()).isEqualTo(ErrorType.FAILED_PRECONDITION.name());
assertThat(exception.getMessage()).isEqualTo("RemoteException: " + ErrorType.FAILED_PRECONDITION.code().name() + " (" + ErrorType.FAILED_PRECONDITION.name() + ") with instance ID " + SERVICE_EXCEPTION.getErrorInstanceId() + ": {key=value}");
}
}
use of com.palantir.conjure.java.api.errors.RemoteException in project conjure-java-runtime by palantir.
the class Retrofit2ClientApiTest method async_retrofit_call_should_throw_RemoteException_for_server_serializable_errors.
@Ignore("TODO(rfink): Async Retrofit calls should produce RemoteException, Issue #625")
@Test
public void async_retrofit_call_should_throw_RemoteException_for_server_serializable_errors() throws Exception {
server.enqueue(new MockResponse().setResponseCode(500).setHeader(HttpHeaders.CONTENT_TYPE, "application/json").setBody(ObjectMappers.newClientJsonMapper().writeValueAsString(ERROR)));
CountDownLatch assertionsPassed = new CountDownLatch(1);
Call<String> call = service.getRelative();
call.enqueue(new retrofit2.Callback<String>() {
@Override
public void onResponse(Call<String> _call, Response<String> _response) {
failBecauseExceptionWasNotThrown(RemoteException.class);
}
@Override
public void onFailure(Call<String> _call, Throwable throwable) {
assertThat(throwable).isInstanceOf(RemoteException.class);
assertThat(((RemoteException) throwable).getError()).isEqualTo(ERROR);
// if you delete this countdown latch then this test will vacuously pass.
assertionsPassed.countDown();
}
});
assertThat(assertionsPassed.await(1, TimeUnit.SECONDS)).as("Callback was executed").isTrue();
}
use of com.palantir.conjure.java.api.errors.RemoteException in project conjure-java-runtime by palantir.
the class RemotingOkHttpCall method execute.
/**
* Process the call. If an IOException is encountered, mark the URL as failed, which indicates that it should be
* avoided for subsequent calls (if {@link UrlSelector} was initialized with a positive
* {@link ClientConfiguration#failedUrlCooldown()}.
*/
@Override
public Response execute() throws IOException {
SettableFuture<Response> future = SettableFuture.create();
enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException exception) {
if (!future.setException(exception)) {
log.warn("Future has already completed", UnsafeArg.of("requestUrl", call.request().url().toString()), exception);
}
}
@Override
public void onResponse(Call call, Response response) {
if (!future.set(response)) {
close(response);
log.warn("Future has already completed, closing the response", UnsafeArg.of("requestUrl", call.request().url().toString()));
}
}
});
try {
// OkHttp call times out (, possibly after a number of retries).
return future.get();
} catch (InterruptedException e) {
getDelegate().cancel();
// Regardless of the cancel above, the call may have succeeded or is going to succeed, and we need to make
// sure the response body is closed correctly in those cases.
Futures.addCallback(future, ResponseClosingCallback.INSTANCE, MoreExecutors.directExecutor());
Thread.currentThread().interrupt();
throw new InterruptedIOException("Call cancelled via interruption");
} catch (ExecutionException e) {
getDelegate().cancel();
if (e.getCause() instanceof IoRemoteException) {
// TODO(rfink): Consider unwrapping the RemoteException at the Retrofit/Feign layer for symmetry, #626
RemoteException wrappedException = ((IoRemoteException) e.getCause()).getWrappedException();
RemoteException correctStackTrace = new RemoteException(wrappedException.getError(), wrappedException.getStatus());
correctStackTrace.initCause(e);
throw correctStackTrace;
} else if (e.getCause() instanceof IoUnknownRemoteException) {
UnknownRemoteException wrappedException = ((IoUnknownRemoteException) e.getCause()).getUnknownRemoteException();
UnknownRemoteException correctStackTrace = new UnknownRemoteException(wrappedException.getStatus(), wrappedException.getBody());
correctStackTrace.initCause(e);
throw correctStackTrace;
} else if (e.getCause() instanceof IOException) {
throw (IOException) e.getCause();
} else {
throw new SafeIoException("Failed to execute call", e);
}
}
}
use of com.palantir.conjure.java.api.errors.RemoteException in project conjure-java by palantir.
the class ConjureExceptionHandlerTest method handles403RemoteException.
@Test
public void handles403RemoteException() throws IOException {
SerializableError remoteError = SerializableError.forException(new ServiceException(ErrorType.create(Code.PERMISSION_DENIED, "Test:ErrorName"), SafeArg.of("foo", "bar")));
exception = new RemoteException(remoteError, ErrorType.PERMISSION_DENIED.httpErrorCode());
Response response = execute();
// Propagates errorInstanceId and does not change error code and name
// Does not propagate args
SerializableError expectedPropagatedError = SerializableError.builder().errorCode(ErrorType.PERMISSION_DENIED.code().toString()).errorName("Test:ErrorName").errorInstanceId(remoteError.errorInstanceId()).build();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
Encodings.json().serializer(new TypeMarker<SerializableError>() {
}).serialize(expectedPropagatedError, stream);
assertThat(response.body().string()).isEqualTo(stream.toString(StandardCharsets.UTF_8));
assertThat(response.code()).isEqualTo(ErrorType.PERMISSION_DENIED.httpErrorCode());
}
use of com.palantir.conjure.java.api.errors.RemoteException in project conjure-java by palantir.
the class ConjureExceptionHandlerTest method handlesRemoteException.
@Test
public void handlesRemoteException() throws IOException {
SerializableError remoteError = SerializableError.forException(new ServiceException(ErrorType.CONFLICT, SafeArg.of("foo", "bar")));
exception = new RemoteException(remoteError, ErrorType.CONFLICT.httpErrorCode());
Response response = execute();
// Propagates errorInstanceId and changes error code and name to INTERNAL
// Does not propagate args
SerializableError expectedPropagatedError = SerializableError.builder().errorCode(ErrorType.INTERNAL.code().toString()).errorName(ErrorType.INTERNAL.name()).errorInstanceId(remoteError.errorInstanceId()).build();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
Encodings.json().serializer(new TypeMarker<SerializableError>() {
}).serialize(expectedPropagatedError, stream);
assertThat(response.body().string()).isEqualTo(stream.toString(StandardCharsets.UTF_8));
// remote exceptions should result in 500 status
assertThat(response.code()).isEqualTo(ErrorType.INTERNAL.httpErrorCode());
}
Aggregations