https://nitinkc.github.io/spring/microservices/spring-exceptions/
curl --location 'localhost:8089/api/word' \
--header 'Content-Type: application/json' \
--data '{
"word":"discover",
"max":"5"
}'
Invoke the number format exception
curl --location 'localhost:8089/api/word' \
--header 'Content-Type: application/json' \
--data '{
"word":"discover",
"max":"word"
}'
For the Request body
@Data
public class MyRequestDTO {
@NotNull
private String max;
@NotNull
@Size(min = 3, max = 10)
private String word;
}
@PostMapping(path = "/word")
public ResponseEntity<List<String>> runController(@RequestBody @Valid MyRequestDTO request) {
}
MethodArgumentNotValidException from the Jakarta Validation
ConstraintViolationException
MethodArgumentNotValidException
curl --location 'localhost:8089/api/word' \
--header 'Content-Type: application/json' \
--data '{
"word":"tt",
"max":"five"
}'
{
"from": "Exception Response :: MethodArgumentNotValidException",
"errorCode": "140 :: Error: :: Validation Error",
"errorMessage": "{word=size must be between 3 and 10}",
"methodName": "POST",
"requestedURI": "/api/word",
"thrownByMethod": "resolveArgument",
"thrownByClass": "org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor",
"exceptionType": null,
"timestamp": "2024-03-06 23:51:08.663 PM MST(GMT-7)"
}
if(!StringUtils.isNumeric(max)){
throw new BadInputException("String is not a Number");
}
curl --location 'localhost:8089/api/word' \
--header 'Content-Type: application/json' \
--data '{
"word":"12345",
"max":"five"
}'
{
"from": "From Exception Response :: handleInputExceptions",
"errorCode": "140 :: Error: :: Validation Error",
"errorMessage": "String is not a Number",
"methodName": "POST",
"requestedURI": "/api/word",
"thrownByMethod": "runController",
"thrownByClass": "com.spring.GlobalExceptionHandling.controller.SimpleController",
"exceptionType": "BadInputException",
"timestamp": "2024-03-06 23:55:18.036 PM MST(GMT-7)"
}
When there is data, either an empty response can be sent or no data found exception can be thrown based on business use case
List<String> data = service.getData(request.getWord(), max);
if (data.isEmpty()){
throw new WordsNotFoundException("No Words found");
}
curl --location 'localhost:8089/api/word' \
--header 'Content-Type: application/json' \
--data '{
"word":"12345",
"max":"5"
}'
{
"from": "From Traceable Error",
"path": "/api/word",
"timestamp": "2024-03-07 00:01:50.683 AM MST(GMT-7)",
"errorCode": "123",
"errorDescription": "ERROR: DB is down",
"exceptionType": "WordsNotFoundException",
"statusCode": "UNAVAILABLE_FOR_LEGAL_REASONS",
"thrownByMethod": "runController",
"thrownByClass": "com.spring.GlobalExceptionHandling.controller.SimpleController",
"exceptionMessage": "No Words found",
"errorTitle": "124 :: Error: :: Some Business Exception"
}
@Documented
@Constraint(validatedBy = EnglishWordValidator.class)
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface EnglishWord {
String message() default "Word must be a valid English word";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
EnglishWordValidator
class implementation
public class EnglishWordValidator implements ConstraintValidator<EnglishWord, String> {
@Override
public void initialize(EnglishWord constraintAnnotation) {
}
@Override
public boolean isValid(String word, ConstraintValidatorContext constraintValidatorContext) {
// implement logic here to check if the word is valid.
// This may involve calling an external service or using an external library.
return checkIfWordIsValidDictionaryWord(word);
}
private boolean checkIfWordIsValidDictionaryWord(String word) {
// For demonstration purposes, all alphanumeric words are non dictionary words
return !StringUtils.isAlphanumeric(word);
}
}
The custom validator can be used as below :-
@Data
public class MyRequestDTO {
@NotNull
private String max;
@NotNull
@Size(min = 3, max = 10)
@EnglishWord
private String word;
}