Commit 34a54890 authored by Krishnakanth Balla's avatar Krishnakanth Balla

Global Exception Handling support added

2023/03/31
parent 94aba332
package com.nisum.bookstore.components;
import org.springframework.boot.web.error.ErrorAttributeOptions;
import org.springframework.boot.web.reactive.error.DefaultErrorAttributes;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.ServerRequest;
import java.util.Map;
@Component
public class MyCustomErrorAttributes extends DefaultErrorAttributes {
@Override
public Map<String, Object> getErrorAttributes(ServerRequest request, ErrorAttributeOptions options) {
Map<String, Object> errorAttributes = super.getErrorAttributes(request, options);
errorAttributes.remove("error");
errorAttributes.put("cause", errorAttributes.get("message"));
errorAttributes.remove("message");
return errorAttributes;
}
}
package com.nisum.bookstore.config;
import org.springframework.boot.autoconfigure.web.WebProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ResourceWebPropertiesConfig {
@Bean
public WebProperties.Resources resources() {
return new WebProperties.Resources();
}
}
package com.nisum.bookstore.controller;
import com.nisum.bookstore.dto.BookDto;
import com.nisum.bookstore.exceptions.BookNotFoundException;
import com.nisum.bookstore.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.server.ResponseStatusException;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
......@@ -16,27 +19,35 @@ public class BookController {
@GetMapping
public Flux<BookDto> getBooks() {
return bookService.getBooks();
return bookService.getBooks().log();
}
@GetMapping("/dummy/{id}")
public Mono<BookDto> getBookDummyById( @PathVariable String id ) {
return bookService.getBookById( id ).log().switchIfEmpty(
Mono.just( new BookDto("1", "name", "author", "publications", "description") ) );
}
@GetMapping("/{id}")
public Mono<BookDto> getBookById( @PathVariable String id ) {
return bookService.getBookById( id );
return bookService.getBookById( id ).log().switchIfEmpty(
BookNotFoundException.monoResponseBookNotFoundException( id )
);
}
@PostMapping
public Mono<BookDto> addBook( @RequestBody BookDto bookDto ) {
return bookService.addBook( Mono.just(bookDto) );
return bookService.addBook( Mono.just(bookDto) ).log();
}
@PutMapping( "/{id}" )
public Mono<BookDto> updateBook( @PathVariable String id, @RequestBody BookDto bookDto ) {
return bookService.updateBook( id, Mono.just(bookDto) );
return bookService.updateBook( id, Mono.just(bookDto) ).log();
}
@DeleteMapping( "/{id}" )
public Mono<Void> deleteBook( @PathVariable String id ) {
return bookService.deleteBook( id );
return bookService.deleteBook( id ).log();
}
}
package com.nisum.bookstore.exceptions;
import org.springframework.http.HttpStatus;
import org.springframework.web.server.ResponseStatusException;
import reactor.core.publisher.Mono;
public class BookNotFoundException {
public static <T> Mono<T> monoResponseBookNotFoundException( String id ) {
return Mono.error(new ResponseStatusException(HttpStatus.NOT_FOUND, "Book ["+ id + "] not found"));
}
}
package com.nisum.bookstore.exceptions;
import com.nisum.bookstore.components.MyCustomErrorAttributes;
import org.springframework.boot.autoconfigure.web.WebProperties;
import org.springframework.boot.autoconfigure.web.reactive.error.AbstractErrorWebExceptionHandler;
import org.springframework.boot.web.error.ErrorAttributeOptions;
import org.springframework.boot.web.reactive.error.ErrorAttributes;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.Order;
import org.springframework.http.MediaType;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.*;
import reactor.core.publisher.Mono;
import java.util.Map;
import java.util.Optional;
@Component
@Order(-2)
public class GlobalExceptionHandler extends AbstractErrorWebExceptionHandler {
ErrorAttributes errorAttributes = null;
public GlobalExceptionHandler(ErrorAttributes errorAttributes,
WebProperties.Resources resources,
ApplicationContext applicationContext,
ServerCodecConfigurer serverCodecConfigurer) {
super(errorAttributes, resources, applicationContext);
this.setMessageWriters( serverCodecConfigurer.getWriters() );
this.errorAttributes = errorAttributes;
}
@Override
protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
return RouterFunctions.route(RequestPredicates.all(), this::formatErrorResponse);
}
private Mono<ServerResponse> formatErrorResponse( ServerRequest serverRequest ) {
Map<String, Object> errorAttributesMap = getErrorAttributes(serverRequest,
ErrorAttributeOptions.defaults()
.including(ErrorAttributeOptions.Include.MESSAGE)
.including(ErrorAttributeOptions.Include.BINDING_ERRORS) );
int status = (int) Optional.ofNullable(errorAttributesMap.get("status")).orElse(500);
return ServerResponse
.status(status)
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(errorAttributesMap));
}
}
......@@ -23,7 +23,7 @@ public class BookServiceImpl implements BookService {
@Override
public Mono<BookDto> getBookById(String id) {
return bookRepo.findById(id).map( book -> AppUtils.entityToDto(book) );
return bookRepo.findById(id).map( book -> AppUtils.entityToDto(book) ).switchIfEmpty(Mono.empty());
}
@Override
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment