How to set message for error reponse status in Spring MVC? - spring

I have a spring mvc handler like this:
#PostMapping("jwtToken")
fun jwtToken(#RequestBody body: JWTToken)
{
val token = body.token
if(token.isNullOrBlank())
throw ResponseStatusException(HttpStatus.UNAUTHORIZED, "Empty token")
}
If i send it an incorrect input, that triggers the exception, i get a reponse body like this:
{
"timestamp": "2020-10-30T03:41:20.305+00:00",
"status": 401,
"error": "Unauthorized",
"message": "",
"path": "/auth/jwtToken"
}
Why is the 'message' field empty in the response when i did assign a message to the exception? How do i set the message field

It might be related to the updated behaviour of the Spring Boot.
https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.3-Release-Notes#changes-to-the-default-error-pages-content
server.error.include-message=always
in .properties should do the trick but I prefer to use my own extended classes like this:
class CustomException(message: String): Exception(message) { ... }

Related

How to describe standard Spring error response in springdoc Schema?

The default server response of a SpringBoot app in case of unhandled errors is
{
"timestamp": 1594232435849,
"path": "/my/path",
"status": 500,
"error": "Internal Server Error",
"message": "this request is failed because of ...",
"requestId": "ba5058f3-4"
}
I want to describe it in a Springdoc annotation for routes of an application.
Assuming that there is a standard class DefaultErrorResponse (just a mock name), it could look like the following:
#Operation(
// ... other details
responses = {
// ... other possible responses
#ApiResponse(
responseCode = "500",
content = #Content(schema = #Schema(implementation = DefaultErrorResponse.class)))
}
)
In a worse case scenario such class does not exists and Spring uses just a Map under the hood for this response creation. Then this annotation will be more verbose, including explicit mention of every field contained in the response.
Obviously for most of the routes this part #ApiResponse(responseCode="500",... is the same, and it would be good to reduce duplication.
What is the proper way to introduce description of the default error response in the documentation?
For error Handling, you use #RestControllerAdvice in combination #ExceptionHandler, in order to refactor the error handling.
These spring annotations are scanned automatically by springdoc-openapi. Without the need to add any additional swagger annotation.

Micronaut GraphQL: How to respond with a non-200 HTTP status code from within GraphQL handler?

Following the docs and here's my exception handler (Kotlin):
#Produces
#Singleton
#Requirements(Requires(classes = [ForbiddenException::class, ExceptionHandler::class]))
class ForbiddenExceptionHandler : ExceptionHandler<ForbiddenException, HttpResponse<*>> {
override fun handle(request: HttpRequest<*>, exception: ForbiddenException): HttpResponse<*> {
return HttpResponse.status<String>(HttpStatus.FORBIDDEN, exception?.message)
}
}
Throwing a ForbiddenException from within my GraphQL handler bubbles the message into the response body, but the status code is always 200.
Example response:
{
"errors": [
{
"message": "Exception while fetching data (/createUser) : FORBIDDEN",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"createUser"
],
"extensions": {
"classification": "DataFetchingException"
}
}
],
"data": null
}
Micronaut version: 1.3.3
Micronaut GraphQL version: 1.3.0.RC1
Disclaimer:
GraphQL is not REST. You are here asking a question related to the core foundation of graphql specification (and any implementations of graphql in general).
They made the choice to embed most errors encountered in the execution of the queries but yet always return a 200 HTTP status. Therefore, you won't be able to change that in your project. It is not a configuration of graphql-java.
The good news is that the format of errors is known. Therefore, you are able to deserialize the error return payload in your application and handle correctly any error that would be thrown by graphql.
Please have a look at this link for in-depth explanations about the main difference between REST and Graphql.

How to handle Exception and return proper HTTP code in Spring webflux?

I have a method which gives response using Mono.fromfuture(result) and which throws CustomException with 400 as status.
Now in my service class, when I call that method, the error and code I am throwing there is not getting propagated to my client(postman). Only the message is what I am seeing.
I am getting this below format: -
{
"timestamp": "2019-02-01T11:13:32.748+0000",
"path": "/some_url",
"status": 500,
"error": "Internal Server Error",
"message": "Unable to fetch Response"
}
Expectation (what I want to achieve) : -
{
"timestamp": "2019-02-01T11:13:32.748+0000",
"path": "/some_url",
"status": 400, // (my own status)
"error": "INVALID_ARGUMENT", // (my own error)
"message": "Unable to fetch Response"
}
My Code:-
public Mono<ResponseObject> fetchResponse(arg) {
return Mono.just(somedata which will give exception)
.flatMap(k -> callExternalService(k))
.onErrorMap(e -> Mono.error(
new BusinessException("Unable to fetch Response", e))
*/* e here is giving :-
"code" : 400,
"message" : "Request contains an invalid argument.",
"status" : "INVALID_ARGUMENT" */*
}
Have you looked at the documentation of the Response class?
You can create a Response of your own, using the static methods in the doc, and send it, instead of Mono.error, in the onErrorMap.
You have to return something like below:
ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(klass, Klass.class);
ServerResponse.status(status).build();//read doc and set for yourself
You can also check this link.

Set Customize Response for Reactive Web Service using Spring Boot and MongoDB as backend

I am developing reactive-spring-boot web service and also using reactive-mongodb to store data. I want to return my customize response for API. example as below:
[
{
"result": [
{
"code": "",
"data": "",
"error": ""
}
]
}
Sample Method:
#PostMapping(value="/addEmployee")
public Mono<Response> addEmployeeDetails(Employee employee){
Response response = new Response();
if(employee.getEmpID() == null){
return response(getResponse());
}
Repository.save(employee);
return response(getResponse());
}
As you see in the code I have response() method which builds the required response.But it mono gives default response as below:
{
"timestamp": "2018-09-29T16:23:21.287+0000",
"status": 500,
"error": "Internal Server Error",
"message": "Internal Server Error",
"path": "/employee"
}
I am not able to set my own status code and error message.

Can you change the 401 error response?

My question is, can you change the structure of the response of the 401 error message?
{
"error": "unauthorized",
"error_description": "No AuthenticationProvider found for org.springframework.security.authentication.UsernamePasswordAuthenticationToken"
}
for example
{
"timestamp" : 123124354,
"status" : 401,
"message" : "The username or password are not valid!"
}
This was answered a while ago: Modify default JSON error response from Spring Boot Rest Controller. Checking the reference guide I would recommend going with the #ControllerAdvice to give you the most flexibility on defining how the JSON response is returned.

Resources