Menelaos Kotsollaris
Menelaos Kotsollaris

Reputation: 5506

How to make RestTemplate never throw exception

I am trying to change the default behavior of RestTemplate which implements the DefaultResponseErrorHandler. I have the following code:

@Override
public boolean hasError(ClientHttpResponse response) throws IOException{
    return false;
}

@Override
public void handleError(ClientHttpResponse response) throws IOException {
}

When I make an HTTP request to my token endpoint:

RestTemplate restTemplate = new RestTemplate();
            restTemplate.setErrorHandler(new NoOpResponseHandler());
            HttpEntity<MultiValueMap<String, Object>> request = initRequest();//a function to retrieve the proper headers of my api
            String oauthUrl = buildUrl("/oauth/token");//this just builds my URL

            // ResponseEntity<?> entity = restTemplate.postForEntity(oauthUrl,
            // request, AccessToken.class);
            ResponseEntity<?> entity = restTemplate.exchange(oauthUrl, HttpMethod.POST, request, String.class);

My NoOpResponseHandler code:

package com.my.test.util;

import java.io.IOException;

import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.client.ResponseErrorHandler;

public class NoOpResponseHandler implements ResponseErrorHandler {


    @Override
    public boolean hasError(ClientHttpResponse response) throws IOException{
        return false;
    }

    @Override
    public void handleError(ClientHttpResponse response) throws IOException {
    }
}

stacktrace:

org.springframework.web.client.ResourceAccessException: I/O error on POST request for "http://localhost:9001/oauth/token": cannot retry due to server authentication, in streaming mode; nested exception is java.net.HttpRetryException: cannot retry due to server authentication, in streaming mode
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:666)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:613)
    at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:531)
    at com.resson.test.login.LoginSteps.lambda$7(LoginSteps.java:73)
    at ✽.Then the login is unsuccessful(features/01-login.feature:19)
Caused by: java.net.HttpRetryException: cannot retry due to server authentication, in streaming mode
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1674)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1474)
    at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480)
    at org.springframework.http.client.SimpleClientHttpResponse.getRawStatusCode(SimpleClientHttpResponse.java:52)
    at org.springframework.http.client.AbstractClientHttpResponse.getStatusCode(AbstractClientHttpResponse.java:33)
    at org.springframework.web.client.MessageBodyClientHttpResponseWrapper.getStatusCode(MessageBodyClientHttpResponseWrapper.java:121)
    at org.springframework.web.client.MessageBodyClientHttpResponseWrapper.hasMessageBody(MessageBodyClientHttpResponseWrapper.java:59)
    at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:82)
    at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:917)
    at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:901)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:655)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:613)
    at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:531)
    at com.resson.test.login.LoginSteps.lambda$7(LoginSteps.java:73)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at cucumber.runtime.Utils$1.call(Utils.java:40)
    at cucumber.runtime.Timeout.timeout(Timeout.java:16)
    at cucumber.runtime.Utils.invoke(Utils.java:34)
    at cucumber.runtime.java.Java8StepDefinition.execute(Java8StepDefinition.java:115)
    at cucumber.runtime.StepDefinitionMatch.runStep(StepDefinitionMatch.java:37)
    at cucumber.runtime.Runtime.runStep(Runtime.java:300)
    at cucumber.runtime.model.StepContainer.runStep(StepContainer.java:44)
    at cucumber.runtime.model.StepContainer.runSteps(StepContainer.java:39)
    at cucumber.runtime.model.CucumberScenario.run(CucumberScenario.java:44)
    at cucumber.runtime.junit.ExecutionUnitRunner.run(ExecutionUnitRunner.java:102)
    at cucumber.runtime.junit.FeatureRunner.runChild(FeatureRunner.java:63)
    at cucumber.runtime.junit.FeatureRunner.runChild(FeatureRunner.java:18)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at cucumber.runtime.junit.FeatureRunner.run(FeatureRunner.java:70)
    at cucumber.api.junit.Cucumber.runChild(Cucumber.java:95)
    at cucumber.api.junit.Cucumber.runChild(Cucumber.java:38)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at cucumber.api.junit.Cucumber.run(Cucumber.java:100)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

The response status is status 401 (unauthorised). On the other hand, on Response Status 400 (bad request) the exception is not thrown.

Any ideas on how to make it never throw exceptions?

Upvotes: 0

Views: 836

Answers (1)

rorschach
rorschach

Reputation: 2947

The problem here is that the Exception you're getting is not considered among the ones the ErrorHandler.. handles.

Check out the source code for RestTemplate. You're getting an IOException that's handled separately.

Upvotes: 2

Related Questions