Message Boards

jaxrs backend always return status 200 even though there is an exception

Yahia Alaoui, modified 2 Years ago.

jaxrs backend always return status 200 even though there is an exception

New Member Posts: 3 Join Date: 4/17/21 Recent Posts

Jaxrs backend always returns status 200 even though there is an exception

The exception shows in the Liferay log, but the frontend receives the status code ok (200)

Any idea ?

thumbnail
Javier Gamarra, modified 2 Years ago.

RE: jaxrs backend always return status 200 even though there is an exceptio

Expert Posts: 348 Join Date: 2/12/15 Recent Posts

Which JAX-RS endpoints? Headless APIs or your custom?

Yahia Alaoui, modified 2 Years ago.

RE: jaxrs backend always return status 200 even though there is an exceptio

New Member Posts: 3 Join Date: 4/17/21 Recent Posts

Thanks Javier, actually it is a basic api created by CLI tool : blade create -t rest and deployed as a jar into liferay.

If we add a line "throw new Exception("test expection)" into the code of the typical "It works" endpoint, the exception is throw only inside Liferay logs, but any frontend consuming the endpoint receives code success 200

@GET
    @Produces("text/plain")
    public String working() {
        return "It works!";
    }

Thanks

thumbnail
Christoph Rabel, modified 2 Years ago.

RE: jaxrs backend always return status 200 even though there is an exceptio

Liferay Legend Posts: 1554 Join Date: 9/24/09 Recent Posts
Assuming that you build your own endpoint:
You need to return a Response instead of a String 

@GET
@Produces("text/plain")
public Response working() {
  if (everything fine) {
     return Response.status(Response.Status.OK).entity("It works").build();
  } else {
    return Response.status(500).build();
  }
}
Yahia Alaoui, modified 2 Years ago.

RE: RE: jaxrs backend always return status 200 even though there is an exce

New Member Posts: 3 Join Date: 4/17/21 Recent Posts

Assuming I may have unepexcted exception, should not be enough just to declare the api as throws Exception ? something like :

@GET
    @Produces("text/plain")
    public String working() throws Exception {

        // something dangerous

        doDangerousWork();        


        return "It works!";
    }

And so if all is good, I have my answer 200, but if something wrong the crash can be captured at the FE level ?

thumbnail
Christoph Rabel, modified 2 Years ago.

RE: jaxrs backend always return status 200 even though there is an exceptio

Liferay Legend Posts: 1554 Join Date: 9/24/09 Recent Posts

The problem is: An exception is thrown, what do you want t send to the frontend? 500? Or was the exception caused by something the frontend did wrong? So, you want to send an appropriate message back.

The easiest way is to handle the exceptions yourself and create an appropriate response.

BUT what you want, should be possible. The question is, which Liferay version do you use? Or to be more precise: Which rest implementation do you use. 7.0 has only CXF, 7.1+ usually uses OSGI Whiteboard.

And these implementations of the specifications provide ways to handle exceptions. OSGI Whiteboard allows you to implement Exception Mappers to handle and "translate" Exceptions into an appropriate response. But I never did that before and I can only point you to the specification:

https://docs.osgi.org/specification/osgi.cmpn/7.0.0/service.jaxrs.html

 

 

thumbnail
Javier Gamarra, modified 2 Years ago.

RE: jaxrs backend always return status 200 even though there is an exceptio

Expert Posts: 348 Join Date: 2/12/15 Recent Posts

It looks like a bug, not sure if CXF or ours. I've filed it here: https://issues.liferay.com/browse/LPS-131519.

You can avoid it by registering an exception mapper that catches all exceptions/errors. That's what the Liferay APIs are doing by default here. That code has a lot of stuff because it returns exceptions formatted like Problem JSON and is registered with a JAX-RS feature. But you can just return easier responses like this:

 @Override
  public Response toResponse(Exception exception) {
    return Response.status(500)
        .entity(ex.getMessage())
        .build();
  }



You can register it to your application like this:

@Component(
	property = {
		"osgi.jaxrs.application.select=(osgi.jaxrs.name=YOUR_APPLICATION)",
		"osgi.jaxrs.extension=true",
		"osgi.jaxrs.name=YOUR_EXCEPTION_NAME"
	},
	service = ExceptionMapper.class
)