How get the bad request message in retrofit 2 - asp.net-web-api

My service return Status:
400 Bad Request
with a message:
Invalid credentials(wrong Password)
I can see this in Postman.
The problem is that i don't know how get the
"400 Bad Request message Invalid credentials(wrong Password)" from my android code.
Here is my code:
call.enqueue(new Callback<JWToken>() {
#Override
public void onResponse(Call<JWToken> call, Response<JWToken> response) {
String strMsg = response.message(); // I get message "Bad Request" without the string "Invalid credentials(wrong Password)"
}
How can I get the message "Invalid credentials(wrong Password)" that my web api returns and I can see in Postman?
Thanks a lot!

Try looking in the errorBody() of the Response. Note that errorBody will only be non-null if isSuccessful is false.
call.enqueue(new Callback<JWToken>() {
#Override
public void onResponse(Call<JWToken> call, Response<JWToken> response) {
if (!response.isSuccessful()) {
String strMsg = response.message();
try {
String errorContent = response.errorBody().string();
} catch (IOException e) {
e.printStackTrace();
}
}
}

Related

Handle error on HttpServletResponse, when OutputStream is used

I have an API method that need send response using HttpServletResponse.getOutputStream(). Is possible to return error response with some http status code when error occurs when outputstream is used like that ? In below code i'm getting Cannot call sendError() after the response has been committed exception and response not completed response but with status 200. I think that because stream is opened and something was written already... Any workaround for this situation?
#GetMapping(path = "/test")
public void test(HttpServletResponse resp) {
try (
OutputStream out = resp.getOutputStream();
) {
// writing to out...
// writing to out...
// ...
// some error occurs
// ...
} catch(IOException e) {
// Cannot call sendError() after the response has been committed
resp.sendError(500, "something wrong");
}
}

Okhttp3.14 Stream closed

I have some usage issue about okhttp in 3.14.9 release
if i want add LoggingInterceptor for each request, how can i get response body, which can only consume once?
And follow is my attemp
public class LoggingRequestInterceptor implements Interceptor {
#Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response response = chain.proceed(request);
log.debug(
"{}, {}, {}, {}, {}, {}, {}",
request.url(),
request.method(),
JSONUtil.toJsonStr(request.body()),
request.headers(),
dup.body() == null ? null : dup.body().string());
return response;
}
}
It will throw exception of stream closed, how to fix it?
Use peekBody for this
val client = OkHttpClient.Builder()
.addInterceptor {
val response = it.proceed(it.request())
println(response.peekBody(1000000).string())
response
}
.build()
I do research for this issue. We can use buffer, which is in RequestBody-source-getBuffer.
Working code is below:
public String getResponseBody(Response response) {
try {
ResponseBody responseBody = response.body();
if (!ObjectUtil.isNull(responseBody)) {
BufferedSource source = responseBody.source();
source.request(Long.MAX_VALUE);
Buffer buffer = source.getBuffer();
return buffer.clone().readString(UTF8);
}
} catch (IOException e) {
log.error("get response body failed: ", e);
}
return null;
}
From ernest-kiwele:
Using a try with a resources block with the response causes this "closed" problem when the response body is read outside of the try block:
try (Response response = client.newCall(request.build()).execute()) {
return response;
} //response.close() called implicitly by the JVM
The fix is to restructure the code to only use the response within the try block.

Extracting response body in aspect for Spring boot application

I would like to log response body with aspect in my Spring Boot application. As of now, I am doing this as follows:
#Pointcut("within(com.web.rest.*)")
public void applicationResourcePointcut() {
}
#AfterReturning(value = ("applicationResourcePointcut()"),
returning = "returnValue")
public void endpointAfterReturning(JoinPoint joinPoint, Object returnValue) throws Throwable {
try {
System.out.println("RESPONSE OBJECT = " + mapper.writeValueAsString(returnValue));
} catch (JsonProcessingException e) {
System.out.println(e.getMessage());
}
}
But here, I am getting full response with Http Status code and other meta data as follows:
RESPONSE OBJECT = {"headers":{"Location":["/api/students/de7cc0b7-dcdf-4f2e-bc26-41525064dd55"],"X-ThreatModelSvc-Alert":["Entit ystudent is created with id:de7cc0b7-dcdf-4f2e-bc26-41525064dd55"]},"body":{"id":"de7cc0b7-dcdf-4f2e-bc26-41525064dd55","name":"Test Name","description":"Test Description","lastModifiedBy":"amallik"},"statusCodeValue":201,"statusCode":"CREATED"}
Here, I just would like to capture the response body. I cannot understand how to extract just the body from the response.

How can I use RestTemplate to verify a Wiremock Fault in integration test?

I have written a number of successful tests to prove the HttpStatus code is being returned correctly, however I am now looking to verify the Fault code returned as below. Usually I would say
assertThat(actualResponse.getStatusCode(), is(status));
to get the Http status code. How can I verify the Fault code? I currently have the below, but I am unsure how to return the fault code from the actualResponse body.
public void shouldReturnSuitableStatusCodeForScenario(String requestFileName,Fault fault, String actualResponseFileName) throws JSONException {
//Given
String createRequest = readJsonFromFile(DIRECTORY, requestFileName);
//When
ResponseEntity<String> actualResponse = stub.postForEntity(HTTP_LOCALHOST_8081 + "/v1/transaction/", createRequest, String.class);
//Then
assertThat(actualResponse, is(fault));
JSONAssert.assertEquals(readJsonFromFile(DIRECTORY, actualResponseFileName), actualResponse.getBody(), true);
}
Current stub, omitted some code for brevit:
.willReturn(aResponse() .withHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE) .withFault(Fault.MALFORMED_RESPONSE_CHUNK) .withBodyFile("/malformed_chunk_response.json")));
In the case you're expecting an error (I'm assuming that stub is a RestTemplate), one way to can extract both the status code and the error body is like this:
String statusText;
int statusCode;
stub.setErrorHandler(new ResponseErrorHandler() {
#Override
boolean hasError(ClientHttpResponse response) throws IOException {
return response.statusCode.isError()
}
#Override
void handleError(ClientHttpResponse response) throws IOException {
statusText = response.getStatusText();
statusCode = response.rawStatusCode;
}
});
stub.postForEntity(HTTP_LOCALHOST_8081 + "/v1/transaction/", createRequest, String.class);

how to decode error code in spring boot fiegn client

I have to implement a error decode for feign client I went to through this link
in that, decode function needs response but how to get this response from fiegn client, below is my feign client.
#FeignClient(name="userservice")
public interface UserClient {
#RequestMapping(
method= RequestMethod.GET,
path = "/userlist")
String getUserByid(#RequestParam(value ="id") String id);
}
I call feign client like this, whenever there is a error FeignException will be caught, but I want to get the proper error codes, like 400, 403 etc .
try {
String str = userClient.getUserByid(id);
return str;
}
catch(FeignException e)
{
logger.error("Failed to get user", id);
}
catch (Exception e)
{
logger.error("Failed to get user", id);
}

Resources