/* Ċ Ġ* ĠCopyright Ġ 2 0 1 9 ĠMO IA ĠGmbH Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* ĠĠĠĠĠĠ Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ* Ċ Ġ*/ Ċ Ċ package Ġio . mo ia . router Ċ Ċ import Ġcom . amazonaws . services . lambda . runtime . Context Ċ import Ġcom . amazonaws . services . lambda . runtime . RequestHandler Ċ import Ġcom . amazonaws . services . lambda . runtime . events . API Gateway Proxy Request Event Ċ import Ġcom . amazonaws . services . lambda . runtime . events . API Gateway Proxy Response Event Ċ import Ġcom . fasterxml . jackson . core . Json ParseException Ċ import Ġcom . fasterxml . jackson . databind . exc . Invalid Definition Exception Ċ import Ġcom . fasterxml . jackson . databind . exc . Invalid FormatException Ċ import Ġcom . fasterxml . jackson . module . kotlin . Missing Kotlin Parameter Exception Ċ import Ġcom . fasterxml . jackson . module . kotlin . jackson ObjectMapper Ċ import Ġcom . google . common . net . MediaType Ċ import Ġorg . slf 4 j . Logger Ċ import Ġorg . slf 4 j . LoggerFactory Ċ import Ġkotlin . reflect . K Class Ċ import Ġkotlin . reflect . jvm . Experimental Reflection On L amb das Ċ import Ġkotlin . reflect . jvm . reflect Ċ Ċ @ Suppress (" Un stable Api Usage ") Ċ abstract Ġclass ĠRequest Handler Ġ: ĠRequest Handler < API Gateway Proxy Request Event , ĠAPI Gateway Proxy Response Event > Ġ{ ĊĊĠĠĠ Ġopen Ġval ĠobjectMapper Ġ= Ġj ack son ObjectMapper () ĊĊĠĠĠ Ġabstract Ġval Ġrouter : ĠRouter ĊĊĠĠĠ Ġprivate Ġval Ġserialization Handler Chain Ġby Ġlazy Ġ{ ĠSerialization Handler Chain ( serialization Handlers ()) Ġ} ĊĠĠĠ Ġprivate Ġval Ġde serialization Handler Chain Ġby Ġlazy Ġ{ ĠDeserial ization Handler Chain ( de serialization Handlers ()) Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġhandle Request ( input : ĠAPI Gateway Proxy Request Event , Ġcontext : ĠContext ): ĠAPI Gateway Proxy Response Event Ġ= ĊĠĠĠĠĠĠĠ Ġinput ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. apply Ġ{ Ġheaders Ġ= Ġheaders . map Keys Ġ{ Ġit . key . lowercase () Ġ} Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. let Ġ{ Ġrouter . filter . then ( this :: handle Request )( it ) Ġ} ĊĊĠĠĠ Ġ@ Suppress (" UN CHECK ED _ CAST ") ĊĠĠĠ Ġprivate Ġfun Ġhandle Request ( input : ĠAPI Gateway Proxy Request Event ): ĠAPI Gateway Proxy Response Event Ġ{ ĊĠĠĠĠĠĠĠ Ġlog . debug (" handling Ġrequest Ġwith Ġmethod Ġ'${ input . http Method }' Ġand Ġpath Ġ'${ input . path }' Ġ- ĠAccept :${ input . accept Header ()} ĠContent - Type :${ input . contentType ()} Ġ$ input ") ĊĠĠĠĠĠĠĠ Ġval Ġroutes Ġ= Ġrouter . routes Ġas ĠList < Router Function < Any , ĠAny >> ĊĠĠĠĠĠĠĠ Ġval Ġmatch Results : ĠList < Request Match Result > Ġ= Ġroutes . map Ġ{ Ġrouter Function : ĠRouter Function < Any , ĠAny > Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmatch Result Ġ= Ġrouter Function . request Predicate . match ( input ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . debug (" match Ġresult Ġfor Ġroute Ġ'$ router Function ' Ġis Ġ'$ match Result '") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( match Result . match ) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmatched Accept Type Ġ= Ġrouter Function . request Predicate . matched Accept Type ( input . accepted Media Types ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: ĠMediaType . parse ( router . default ContentType ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġhandler : ĠHandler Function < Any , ĠAny > Ġ= Ġrouter Function . handler ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresponse Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( missing Permissions ( input , Ġrouter Function )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠApiException (" missing Ġpermissions ", Ġ" MISSING _ PERMISSION S ", Ġ 4 0 3 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrequest Body Ġ= Ġdeserialize Request ( handler , Ġinput ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrequest Ġ= ĠRequest ( input , Ġrequest Body , Ġrouter Function . request Predicate . path Pattern ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( handler Ġas ĠHandler Function < *, Ġ*> )( request ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexception To Response Entity ( e , Ġinput ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġcreate Response ( matched Accept Type , Ġresponse ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmatch Result ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġhandle Non Direct Match ( MediaType . parse ( router . default ContentType ), Ġmatch Results , Ġinput ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġexception To Response Entity ( e : ĠException , Ġinput : ĠAPI Gateway Proxy Request Event ) Ġ= ĊĠĠĠĠĠĠĠ Ġwhen Ġ( e ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠApiException Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe . to Response Entity ( this :: create Error Body ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. also Ġ{ Ġlog ApiException ( e , Ġinput ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexception To Response Entity ( e ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. also Ġ{ Ġlog Unknown Exception ( e , Ġinput ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġmissing Permissions ( input : ĠAPI Gateway Proxy Request Event , Ġrouter Function : ĠRouter Function < Any , ĠAny >) Ġ= ĊĠĠĠĠĠĠĠ Ġ! permission Handler Supplier ()( input ). has Any Required Permission ( router Function . request Predicate . required Permissions ) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠHook Ġto Ġbe Ġable Ġto Ġoverride Ġthe Ġway ĠApi Exceptions Ġare Ġlogged . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġopen Ġfun Ġlog ApiException ( e : ĠApiException , Ġinput : ĠAPI Gateway Proxy Request Event ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlog . info (" Ca ught Ġapi Ġerror Ġwhile Ġhandling Ġ${ input . http Method } Ġ${ input . path } Ġ- Ġ$ e ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠHook Ġto Ġbe Ġable Ġto Ġoverride Ġthe Ġway Ġnon - Api Exceptions Ġare Ġlogged . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġopen Ġfun Ġlog Unknown Exception ( e : ĠException , Ġinput : ĠAPI Gateway Proxy Request Event ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlog . error (" Ca ught Ġexception Ġhandling Ġ${ input . http Method } Ġ${ input . path } Ġ- Ġ$ e ", Ġe ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġopen Ġfun Ġserialization Handlers (): ĠList < Serialization Handler > Ġ= ĠlistOf ( ĊĠĠĠĠĠĠĠ ĠJson Serialization Handler ( object Mapper ), ĠPlain Text Serialization Handler () ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġopen Ġfun Ġde serialization Handlers (): ĠList < Deserialization Handler > Ġ= ĠlistOf ( ĊĠĠĠĠĠĠĠ ĠJson Deserialization Handler ( object Mapper ) ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġopen Ġfun Ġpermission Handler Supplier (): Ġ( r : ĠAPI Gateway Proxy Request Event ) Ġ-> ĠPermission Handler Ġ= ĊĠĠĠĠĠĠĠ Ġ{ ĠNo Op Permission Handler () Ġ} ĊĊĠĠĠ Ġ@ Experimental Reflection On L amb das ĊĠĠĠ Ġprivate Ġfun Ġdeserialize Request ( ĊĠĠĠĠĠĠĠ Ġhandler : ĠHandler Function < Any , ĠAny >, ĊĠĠĠĠĠĠĠ Ġinput : ĠAPI Gateway Proxy Request Event ĊĠĠĠ Ġ): ĠAny ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġrequest Type Ġ= Ġhandler . reflect () !!. parameters . first (). type . arguments . first (). type ĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequest Type ?. classifier Ġas ĠK Class < *> Ġ== ĠUnit :: class Ġ-> ĠUnit ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinput . body Ġ== Ġnull Ġ&& Ġrequest Type . is Marked Nullable Ġ-> Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinput . body Ġ== Ġnull Ġ-> Ġthrow ĠApiException (" no Ġrequest Ġbody Ġpresent ", Ġ" REQUEST _ BODY _ MISSING ", Ġ 4 0 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinput . body Ġis ĠString Ġ&& Ġrequest Type . classifier Ġas ĠK Class < *> Ġ== ĠString :: class Ġ-> Ġinput . body ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġde serialization Handler Chain . deserialize ( input , Ġrequest Type ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġhandle Non Direct Match ( default ContentType : ĠMediaType , Ġmatch Results : ĠList < Request Match Result >, Ġinput : ĠAPI Gateway Proxy Request Event ): ĠAPI Gateway Proxy Response Event Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġno Ġdirect Ġmatch ĊĠĠĠĠĠĠĠ Ġval Ġapi Exception Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmatch Results . any Ġ{ Ġit . match Path Ġ&& Ġit . match Method Ġ&& Ġ! it . match ContentType Ġ} Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠApiException ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠhttpResponse Status Ġ= Ġ 4 1 5 , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage Ġ= Ġ" Unsupported ĠMedia ĠType ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcode Ġ= Ġ" UNSUPPORTED _ MEDIA _ TYPE " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmatch Results . any Ġ{ Ġit . match Path Ġ&& Ġit . match Method Ġ&& Ġ! it . match Accept Type Ġ} Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠApiException ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠhttpResponse Status Ġ= Ġ 4 0 6 , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage Ġ= Ġ" Not ĠAccept able ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcode Ġ= Ġ" NOT _ ACCEPT ABLE " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmatch Results . any Ġ{ Ġit . match Path Ġ&& Ġ! it . match Method Ġ} Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠApiException ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠhttpResponse Status Ġ= Ġ 4 0 5 , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage Ġ= Ġ" Method ĠNot ĠAllowed ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcode Ġ= Ġ" METHOD _ NOT _ ALLOWED " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> ĠApiException ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠhttpResponse Status Ġ= Ġ 4 0 4 , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage Ġ= Ġ" Not Ġfound ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcode Ġ= Ġ" NOT _ FOUND " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġcreate Response ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠcontentType Ġ= Ġinput . accepted Media Types (). first OrNull () Ġ?: Ġdefault ContentType , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresponse Ġ= Ġapi Exception . to Response Entity ( this :: create Error Body ) ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCustom ize Ġthe Ġformat Ġof Ġan Ġapi Ġerror ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġopen Ġfun Ġcreate Error Body ( error : ĠApi Error ): ĠAny Ġ= Ġerror ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCustom ize Ġthe Ġformat Ġof Ġan Ġun process able Ġentity Ġerror ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġopen Ġfun Ġcreate Un process able Entity Error Body ( errors : ĠList < Un process able Entity Error >): ĠAny Ġ= Ġerrors ĊĊĠĠĠ Ġprivate Ġfun Ġcreate Un process able Entity Error Body ( error : ĠUn process able Entity Error ): ĠAny Ġ= Ġcreate Un process able Entity Error Body ( listOf ( error )) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠHook Ġto Ġcustomize Ġthe Ġway Ġnon - Api Exceptions Ġare Ġconverted Ġto ĠResponseEntity . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠSome Ġcommon Ġexceptions Ġare Ġalready Ġhandled Ġin Ġthe Ġdefault Ġimplementation . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġopen Ġfun Ġexception To Response Entity ( ex : ĠException ) Ġ= ĊĠĠĠĠĠĠĠ Ġwhen Ġ( ex ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠJson ParseException Ġ-> ĠResponseEntity ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 4 2 2 , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcreate Un process able Entity Error Body ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠUn process able Entity Error ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage Ġ= Ġ" INVALID _ ENTITY ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcode Ġ= Ġ" ENTITY ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpath Ġ= Ġ"", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdetails Ġ= Ġmap Of ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" payload " Ġto Ġex . request Payload AsString . or Empty (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" message " Ġto Ġex . message . or Empty () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠInvalid Definition Exception Ġ-> ĠResponseEntity ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 4 2 2 , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcreate Un process able Entity Error Body ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠUn process able Entity Error ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage Ġ= Ġ" INVALID _ FIELD _ FORMAT ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcode Ġ= Ġ" FIELD ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpath Ġ= Ġex . path . last (). fieldName . or Empty (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdetails Ġ= Ġmap Of ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" cause " Ġto Ġex . cause ?. message . or Empty (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" message " Ġto Ġex . message . or Empty () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠInvalid FormatException Ġ-> ĠResponseEntity ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 4 2 2 , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcreate Un process able Entity Error Body ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠUn process able Entity Error ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage Ġ= Ġ" INVALID _ FIELD _ FORMAT ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcode Ġ= Ġ" FIELD ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpath Ġ= Ġex . path . last (). fieldName . or Empty () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠMissing Kotlin Parameter Exception Ġ-> ĠResponseEntity ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 4 2 2 , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcreate Un process able Entity Error Body ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠUn process able Entity Error ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage Ġ= Ġ" MISSING _ REQUIRED _ FIELDS ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcode Ġ= Ġ" FIELD ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpath Ġ= Ġex . parameter . name . or Empty () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> ĠResponseEntity ( 5 0 0 , Ġcreate Error Body ( ApiError ( ex . message . or Empty (), Ġ" INTERNAL _ SERVER _ ERROR "))) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġopen Ġfun Ġ< T > Ġcreate Response ( contentType : ĠMediaType , Ġresponse : ĠResponseEntity < T >): ĠAPI Gateway Proxy Response Event Ġ= ĊĠĠĠĠĠĠĠ Ġwhen Ġ( response . body Ġ!= Ġnull Ġ&& Ġserialization Handler Chain . supports ( contentType , Ġresponse . body )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtrue Ġ-> ĠcontentType ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfalse Ġ-> ĠMediaType . parse ( router . default ContentType ) ĊĠĠĠĠĠĠĠ Ġ}. let Ġ{ Ġfinal ContentType Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAPI Gateway Proxy Response Event () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. with StatusCode ( response . statusCode ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. with Headers ( response . headers . to Mutable Map (). apply Ġ{ Ġput (" Content - Type ", Ġfinal ContentType . toString ()) Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. with Body ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresponse . body ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġserialization Handler Chain . serialize ( final ContentType , Ġit Ġas ĠAny ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlog : ĠLogger Ġ= ĠLoggerFactory . getLogger ( RequestHandler :: class . java ) ĊĠĠĠ Ġ} Ċ } Ċ