quarkusio / quarkus

Quarkus: Supersonic Subatomic Java.
https://quarkus.io
Apache License 2.0
13.58k stars 2.63k forks source link

Eclipse MicroProfile RestClient always returns Unknown error. #9360

Closed carlosepdsJava-zz closed 1 year ago

carlosepdsJava-zz commented 4 years ago

Describe the bug Calling a restAPI endpoint, using RestClient. The error message generated by the endpoint is not returned in the API exception.

Using postman, this is original response error:

{
    "error": "unsupported_grant_type",
    "error_description": "The authorization grant type is not supported by the authorization server. Configured grant types: [refresh_token, password, authorization_code, implicit]."
}

Expected behavior The expectation is that any service called will return the error message generated by the endpoint, and not an unknown error.

Actual behavior the original error message is being ignored, and returns an unknown error. WebApplicationException: Unknown error, status code 400

To Reproduce any application you use Eclipse MicroProfile RestClient will have this problem.

Environment:

gastaldi commented 4 years ago

@radcortez could this be a RestEasy client bug? @carlosepdsJava any chance you can create a simple reproducer project with a small test?

radcortez commented 4 years ago

@carlosepdsJava already reached out to me about this. He shared the project with me and I don't think the issue is with RestEasy.

I don't have the code anymore, but as far as I remember, the Rest Client endpoint was mapped directly with a DTO, so when you get an error, the payload doesn't match the DTO. My recommendation was to map it to Response, check the status code and use readEntity with the expected DTO.

carlosepdsJava-zz commented 4 years ago

@radcortez could this be a RestEasy client bug? @carlosepdsJava any chance you can create a simple reproducer project with a small test?

@gastaldi I will generate an example.

@radcortez sorry but i didn't understand your recommendation.

carlosepdsJava-zz commented 4 years ago

@gastaldi and @radcortez , follows address of the GIT repository of the code https://github.com/carlosepdsJava/9360-9359.git

in that same code, I'm also having a problem with the @Valid annotation. Issue # 9359

geoand commented 4 years ago

I can't reproducer the problem.

By executing

POST http://localhost:8080/api/login/v2/login
Accept: application/json
Content-Type: application/json
Cache-Control: no-cache

{
 "userName": "teste@teste.com.br", "password": "*******"
}

I get:

HTTP/1.1 405 Method Not Allowed
Transfer-Encoding: chunked
Server: nginx
X-Content-Type-Options: nosniff
Public-Key-Pins-Report-Only: pin-sha256="******"; pin-sha256="******"; pin-sha256="******"; pin-sha256="******"; max-age=60; report-uri="https://okta.report-uri.com/r/default/hpkp/reportOnly"
Connection: keep-alive
Content-Length: 174
Date: Thu, 21 May 2020 15:15:27 GMT
Content-Type: application/json

{
  "errorCode": "E0000022",
  "errorSummary": "The endpoint does not support the provided HTTP method",
  "errorLink": "E0000022",
  "errorId": "********",
  "errorCauses": []
}

Response code: 405 (Method Not Allowed); Time: 1627ms; Content length: 174 bytes
carlosepdsJava-zz commented 4 years ago

I can't reproducer the problem.

By executing

POST http://localhost:8080/api/login/v2/login
Accept: application/json
Content-Type: application/json
Cache-Control: no-cache

{
 "userName": "teste@teste.com.br", "password": "*******"
}

I get:

HTTP/1.1 405 Method Not Allowed
Transfer-Encoding: chunked
Server: nginx
X-Content-Type-Options: nosniff
Public-Key-Pins-Report-Only: pin-sha256="******"; pin-sha256="******"; pin-sha256="******"; pin-sha256="******"; max-age=60; report-uri="https://okta.report-uri.com/r/default/hpkp/reportOnly"
Connection: keep-alive
Content-Length: 174
Date: Thu, 21 May 2020 15:15:27 GMT
Content-Type: application/json

{
  "errorCode": "E0000022",
  "errorSummary": "The endpoint does not support the provided HTTP method",
  "errorLink": "E0000022",
  "errorId": "********",
  "errorCauses": []
}

Response code: 405 (Method Not Allowed); Time: 1627ms; Content length: 174 bytes

Sorry, i change method call to GET. I'm using postman to call the API. Do not curl.

making the POST call via postman, nothing returns. but using curl really returns this error that you showed.

curl --location --request POST 'http://localhost:8080/api/login/v2/login' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Cache-Control: no-cache' \
--header 'Content-Type: text/plain' \
--data-raw '{
  "userName": "teste@teste.com.br",
  "password": "B@lalaik@123"
}'
{"errorCode":"E0000022","errorSummary":"The endpoint does not support the provided HTTP method","errorLink":"E0000022","errorId":"oaexmg1CTUvRE2K7XtR6K24Cw","errorCauses":[]}

call made via curl with correct method(no error is returned.):

curl --location --request GET 'http://localhost:8080/api/login/v2/login' \
--header 'Content-Type: application/json' \
--header 'Content-Type: text/plain' \
--data-raw '{
  "userName": "teste@teste.com.br",
  "password": "B@lalaik@123"
}'
geoand commented 4 years ago

The stuff I pasted above was using IntelliJ's REST facility.

So now I am confused at to what the problem is :)

carlosepdsJava-zz commented 4 years ago

The stuff I pasted above was using IntelliJ's REST facility.

So now I am confused at to what the problem is :)

Unbelievable!!!! I'm using Postman, to make calls to the API, and I did the test now and via curl the error that is generated by the endpoint, the restclient brought.

curl --location --request POST 'http://localhost:8080/api/login/v2/login' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Cache-Control: no-cache' \
--header 'Content-Type: text/plain' \
--data-raw '{
  "userName": "teste@teste.com.br",
  "password": "B@lalaik@123"
}' 

{"error":"invalid_grant","error_description":"The credentials provided were invalid."}%

but this error does not generate an exception in the application.

geoand commented 4 years ago

Can you try with --header 'Content-Type: application/json'?

carlosepdsJava-zz commented 4 years ago

when I put try catch, the exception that is returned is: Unknown error, status code 400.

       try {
            return loginService.login(accessLogin);
        } catch (Exception ex) {
            System.out.println(ex.getMessage());
        }

the error message is not printed in the exception as it was in curl.

carlosepdsJava-zz commented 4 years ago

Can you try with --header 'Content-Type: application/json'?

Yeap!

arunsai271 commented 3 years ago

Me also facing the same issue, In my case, the exception object is giving proper status code but not the response body. Any suggestions on how to get the exact response entity?

akrtkv commented 3 years ago

Same issue quarkus 1.13.0.Final. Any news?

radcortez commented 3 years ago

@deepfunction do you have a reproducer?

akrtkv commented 3 years ago

@radcortez

I just created projects for test. And all working fine. I dont understand whats wrong with my main project))

radcortez commented 3 years ago

I hate when that happens :(

Any change you can figure something out?

julio-rocha-coderoad-com commented 3 years ago

@deepfunction I had the same issue. The response for 4xx codes were arriving with empty payload to my fallback handler after update quarkus from 1.7.3.Final to 2.1.2.Final

I tried adding an exception mapper and the response arrives as expected there.

@Priority(1)
public class MyExceptionMapper implements ResponseExceptionMapper<RuntimeException> {
    @Override
    public RuntimeException toThrowable(Response response) {
        return new WebApplicationException(response);
    }
}
cherlo commented 2 years ago

Having same issue. I tried setting the Produces content type to application/json which matches the content-type of the response. The response is definitely returning as I can see it in the wire log. When attempting to read the entity from the WAE, this is the error: RESTEASY002340: Client receive processing failure.: javax.ws.rs.ProcessingException: java.lang.IllegalStateException: RESTEASY003291: Input stream was empty, there is no entity. Quarkus version 2.0.1.Final

Update: After adding the ResponseExceptionMapper as @julio-rocha-coderoad-com stated and then registered it as a provider in the restclient, I was able to read the response body.

bennetelli commented 2 years ago

I am having the same issue. With Quarkus 2.3.1, 2.4.0 and 2.5.0.

My case is: I am calling an url (http) locally, then the endpoint uses a RestClient (with RegisterRestClient annotation) to call another url.

And the issue happens when I try to trigger the url with http instead of https. Maybe this is helpful for someone here.

ps: the ResponseExceptionMapper example didn't lead to more informations about the unknown error.

alexbrigido commented 2 years ago

This works for me:

if(e instanceof WebApplicationException) { Response response = ((WebApplicationException) e).getResponse(); MyErrorEntity entity = response.readEntity(MyErrorEntity.class);
}

Hope this is helpful

bennetelli commented 2 years ago

Will give it a try @alexbrigido, thanks.

but. tbh.. what a hack :-D :-D

brunobastosg commented 2 years ago

I also have the same problem using Quarkus 2.5.4.

@julio-rocha-coderoad-com 's solution works, though.

geoand commented 1 year ago

Is this still an issue? Moreover, is it an issue with the quarkus-rest-client-reactive?

geoand commented 1 year ago

Closing for lack of feedback.