0

I've got a DTO that represents bank accounts:

@Data
@AllArgsConstructor
public class AccountDto {
    @NonNull
    private String id;
    @NonNull
    private Long balance;
    @NonNull
    private Currency currency;
}

Currency is an enum where I've put several currency identifiers:

public enum Currency {
    AFN,
    EUR,
    ALL,
    DZD,
    USD,
    AOA,
.
.
.
}

This is my controller method for POST-ing new transactions:

@PostMapping("/newaccount")
    public ResponseEntity<AccountDto> postNewAccount(@RequestBody AccountDto accountDto){
        accountService.storeAccount(accountDto);
        return ResponseEntity.ok(accountDto);
    }

I want to test what happens when I make a POST with a value for currency that is NOT within the accepted enum values, for example UNK (for UNKNOWN). So I make the following POST through Postman:

{
    "sourceAccountId": "acc1",
    "targetAccountId": "acc2",
    "amount": 10.0,
    "currency": "UNK"
}

And I get the raw message of the InvalidFormatException:

JSON parse error: Cannot deserialize value of type `com.agilebank.model.Currency` from String "UNK": not one of the values accepted for Enum class: [FJD, UGS, SCR, MXN, BBD, CDF, HNL, LVR, ZAR, STN, CUC, BSD, SDG, IQD, CUP, SDP, TWD, ZRZ, RSD, UYI, MYR, UYN, FKP, UYP, XOF, ARA, UYU, CVE, UYW, OMR, MZE, KES, BTN, GNE, GNF, SVC, MZN, ARS, ARY, IRR, XPD, XPF, BDT, LYD, KWD, XPT, RUB, BEC, ISK, BEF, MKD, BEL, DZD, RUR, SGD, PAB, KGS, HRD, XAF, XAG, ATS, HRK, MLF, VNC, VND, TZS, AUD, CHW, KHR, KYD, IDR, XBB, XBC, XBD, BWP, TJR, TJS, AED, RWF, DKK, BGJ, BGK, BGL, YUD, BGN, NOK, MMK, ZWL, YUM, YUN, LKR, CZK, ZWR, XCD, XSU, HTG, AFA, BHD, PTE, SZL, YER, AFN, BYB, RHD, NPR, AWG, MNT, GBP, BYN, HUF, BYR, BIF, XUA, XDR, BZD, MOP, NAD, PEH, PEI, WST, PEN, FRF, TMT, CLF, PES, GTQ, CLP, XEU, TND, SLL, AYM, XFO, KMF, DOP, XFU, GEK, GEL, MAD, AZM, TOP, UAH, UAK, ERN, TPE, MRO, CNY, MRU, ESA, ESB, GWE, PHP, BMD, NUC, PYG, GWP, JMD, ESP, COP, USD, COU, USN, ETB, ECS, LAK, SOS, BND, LRD, ALK, ALL, GHC, VES, MTL, MTP, ILP, TRL, GHP, ILS, GHS, BOB, AMD, LBP, TRY, JOD, HKD, EUR, BOP, LSL, CAD, BOV, MUR, EEK, GIP, ROL, RON, CRC, NGN, PKR, ANG, SAR, SRD, MVQ, MVR, LTT, INR, KRW, PLN, JPY, CSD, SBD, CSJ, CSK, LUF, PLZ, AON, MWK, LUL, AOR, BAD, MGA, NIC, FIM, DEM, BAM, SSP, BRB, BRC, NIO, BRE, NZD, BRL, BRN, STD, ZAL, UGX, MXV, SDD, ZRN, GMD, SUR, SEK, ARP, MZM, QAR, NLG, GNS, THB, BUK, ISJ, CHC, CHF, XRE, XAU, XBA, YDD, SHP, ZWD, SYP, ZWN, IEP, GRD, SIT, KZT, XTS, SKK, TMM, AZN, XXX, VEB, LAJ, VUV, ECV, ZMW, ILR, GYD, MDL, LSM, ROK, TTD, SRG, DDM, AOA, LUC, AOK, MGF, EGP, BRR, LVL, MXP, UGW, UZS, ITL, DJF, CHE, ADP, GQE, CYP, ZWC, PGK, USS, VEF, ZMK, KPW, LTL]

I don't quite like this low-level, language-specific and wordy message, so I've tried to intercept the InvalidFormatException and return something custom through a @RestControllerAdvice class:

@RestControllerAdvice
public class ExceptionAdvice {

    @ResponseBody
    @ExceptionHandler(InvalidFormatException.class)
    @ResponseStatus(HttpStatus.NOT_ACCEPTABLE)
    public String invalidFormatException(InvalidFormatException exc){
        return "foo";
    }

}

But I still get the raw message displayed above. Any ideas?

Jason
  • 2,495
  • 4
  • 26
  • 37

1 Answers1

0

It turns out that in a previous method in my @RestControllerAdvice class I had the following:

 @ResponseBody
    @ExceptionHandler(HttpMessageNotReadableException.class)
    @ResponseStatus(HttpStatus.NOT_ACCEPTABLE)
    public String messageNotReadableException(HttpMessageNotReadableException ex) {
        return ex.getMessage();
    }

and it was taking precedence over the handler for InvalidFormatException. That handler can now intercept the exception thrown during the unsuccessful deserialization of "UNK".

Jason
  • 2,495
  • 4
  • 26
  • 37