/* Ċ Ġ* ĠCopyright ĠIBM ĠCorp . ĠAll ĠRights ĠReserved . Ċ Ġ* Ċ Ġ* ĠSPDX - License - Identifier : ĠApache - 2 . 0 Ċ Ġ*/ Ċ Ċ package Ġcom . we aver . cord a . app . interop . flows Ċ Ċ import Ġcom . we aver . protos . common . query . Query OuterClass Ċ import Ġarrow . core . Either Ċ import Ġarrow . core . Left Ċ import Ġarrow . core . Right Ċ import Ġarrow . core . flatMap Ċ import Ġco . parallel universe . fib ers . Suspend able Ċ import Ġcom . google . protobuf . ByteString Ċ import Ġcom . we aver . protos . common . interop _ payload . Interop Payload OuterClass Ċ import Ġcom . we aver . protos . common . state . State Ċ import Ġcom . we aver . protos . cord a . ViewData OuterClass Ċ import Ġnet . cord a . core . contracts . Linear State Ċ import Ġnet . cord a . core . contracts . Unique Identifier Ċ import Ġnet . cord a . core . flows . Flow Logic Ċ import Ġnet . cord a . core . flows . Start able By RPC Ċ import Ġnet . cord a . core . node . services . query By Ċ import Ġnet . cord a . core . node . services . vault . Query Criteria Ċ import Ġjava . security . Message Digest Ċ import Ġjava . time . Instant Ċ import Ġjava . util .* Ċ Ċ /** Ċ Ġ* ĠThe ĠHandle External Request Ġflow Ġprocesses Ġrequests Ġthat Ġcome Ġfrom Ġexternal Ġnetworks . Ċ Ġ* Ċ Ġ* ĠThe Ġflow Ġcoordinates Ġthe Ġfollowing : Ċ Ġ* Ġ 1 . ĠChecks Ġthe Ġvalidity Ġof Ġquery Ġsignature Ċ Ġ* Ġ 2 . ĠChecks Ġthat Ġthe Ġcertificate Ġof Ġthe Ġrequest er Ġis Ġvalid Ġaccording Ġto Ġthe Ġnetwork 's Ġ[ Membership ] Ċ Ġ* Ġ 3 . ĠRes olves Ġflow Ġlisted Ġin Ġthe Ġview Ġaddress Ċ Ġ* Ġ 4 . ĠChecks Ġthe Ġaccess Ġcontrol Ġpolicy Ġfor Ġthe Ġrequest er Ġand Ġview Ġaddress Ġis Ġmet Ċ Ġ* Ġ 5 . ĠCalls Ġapplication ĠCor D app Ġflow Ċ Ġ* Ġ 6 . ĠSign s Ġthe Ġrequested Ġview Ġon Ġthe Ġstring ified ĠJSON Ġconverted Ġto Ġa ĠBase 6 4 ĠByteArray Ċ Ġ* Ġ 7 . ĠCreates Ġthe ĠView Ġto Ġbe Ġreturned Ċ Ġ* Ċ Ġ* Ġ@ property Ġquery ĠThe Ġquery Ġthat Ġis Ġsent Ġby Ġthe Ġrequesting Ġnetwork . Ċ Ġ*/ Ċ @ Start able By RPC Ċ class ĠHandle External Request ( val Ġquery : ĠQuery OuterClass . Query ) Ġ: ĠFlow Logic < Either < Error , ĠState . View >>() Ġ{ ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġcall () Ġmethod Ġruns Ġthe Ġflow Ġlogic . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠAny Ġerrors Ġthat Ġare Ġencountered Ġduring Ġthe Ġverification Ġof Ġthe Ġrequest Ġare Ġpropag ated Ġup Ġto Ġthe ĊĠĠĠĠ Ġ* ĠLeft ( Error ) Ġtype . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ return Ġreturns Ġan ĠEither Ġwith Ġan ĠError Ġor Ġa ĠView Ġcontaining Ġthe Ġmetadata Ġand Ġview Ġdata . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Suspend able ĊĠĠĠ Ġoverride Ġfun Ġcall (): ĠEither < Error , ĠState . View > Ġ= Ġtry Ġ{ ĊĠĠĠĠĠĠĠ Ġprintln (" Received Ġquery Ġfrom Ġforeign Ġnetwork Ġ$ query ") ĊĊĠĠĠĠĠĠĠ Ġ// Ġ 1 . ĠCheck Ġvalidity Ġof Ġrequest Ġsignature ĊĠĠĠĠĠĠĠ Ġverify Node Signature ( query . certificate , Ġquery . request or Signature , Ġ( query . address Ġ+ Ġquery . nonce ). toByteArray ()). flatMap Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġget Certificate FromString ( query . certificate ). flatMap Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ 2 . ĠCheck Ġthat Ġthe Ġcertificate Ġof Ġthe Ġrequest er Ġis Ġvalid Ġaccording Ġto Ġthe Ġsecurity Domain 's ĠMembers hip ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġverify Member In Security Domain ( it , Ġquery . request ing Network , Ġquery . request ing Org , Ġservice Hub ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ}. flatMap Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ 3 . ĠResolve Ġthe Ġflow Ġfrom Ġthe Ġaddress Ġin Ġthe Ġquery ĊĠĠĠĠĠĠĠĠĠĠĠ Ġparse C ord a View Address ( query . address ). flatMap Ġ{ Ġc ord a View Address Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresolve Flow ( cord a View Address . flow Name , Ġc ord a View Address . flow Args ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ}. flatMap Ġ{ Ġflow Logic Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprintln (" Resolved Ġflow Ġto Ġ$ flow Logic \ n ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ 4 . ĠCheck Ġaccess Ġcontrol Ġpolicy Ġis Ġmet Ġfor Ġthe Ġrequest er Ġand Ġview Ġaddress ĊĠĠĠĠĠĠĠĠĠĠĠ Ġverify Access To Flow ( query , Ġservice Hub ). flatMap Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ 5 . ĠCall Ġthe Ġapplication ĠCor D app Ġflow ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġflow Result Ġ= Ġsub Flow ( flow Logic ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprintln (" Flow Ġresult : Ġ$ flow Result \ n ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠRight ( flow Result ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprintln (" Flow ĠError : ĠError Ġcalling Ġthe Ġrequested Ġflow : Ġ${ e . message }. \ n ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLeft ( Error (" Flow ĠError : Ġ${ e . message } ")) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ}. flatMap Ġ{ Ġflow Result Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġinter op Payload Ġ= ĠInter op Payload OuterClass . Interop Payload . newBuilder () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Address ( query . address ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Payload ( ByteString . copyFrom ( flow Result )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ 7 . ĠAs semble Ġthe Ġview Ġfrom Ġthe Ġresult Ġreturned Ġfrom Ġthe Ġflow ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsub Flow ( Create Node Signature Flow ( interop Payload . toByteArray ())). flatMap Ġ{ Ġsignature Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprintln (" calling Ġcreate View Ġfrom ĠHandle External Request ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġview Ġ= Ġcreate View ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinter op Payload . toByteArray (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsignature , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconvert Certificate To Base 6 4 Pem ( our Identity And Cert . certificate . encoded ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġour Identity . name . organisation ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprintln (" Generated Ġview : Ġ$ view Ġ\ n ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġview ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠ Ġprintln (" Flow ĠError : ĠError Ġhandling Ġthe Ġexternal Ġrequest : Ġ${ e . message }. \ n ") ĊĠĠĠĠĠĠĠ ĠLeft ( Error (" Flow ĠError : ĠError Ġhandling Ġthe Ġexternal Ġrequest : Ġ${ e . message } ")) ĊĠĠĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠThe ĠQuery State Ġflow Ġallows Ġfor Ġfinding Ġthe ĠLinear State 's Ġfor Ġare Ġdata Ġin Ġthe Ġvault Ċ Ġ* Ċ Ġ* ĠThis Ġflow Ġis Ġcurrently Ġonly Ġbeing Ġused Ġfor Ġtesting Ġpurposes . Ċ Ġ*/ Ċ @ Start able By RPC Ċ class ĠQuery State () Ġ: ĠFlow Logic < ByteArray >() Ġ{ ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġcall () Ġmethod Ġruns Ġthe Ġflow Ġlogic . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ return Ġreturns Ġthe ĠLinear State 's Ġcorresponding Ġto Ġthe Ġstate Ġin Ġthe Ġvault ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Suspend able ĊĠĠĠ Ġoverride Ġfun Ġcall (): ĠByteArray Ġ{ ĊĠĠĠĠĠĠĠ Ġprintln (" Query ing Ġfor Ġstates ") ĊĠĠĠĠĠĠĠ Ġvar Ġstates : ĠList < Linear State >? ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstates Ġ= Ġservice Hub . vault Service ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. query By < Linear State >() ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. states ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġit . state . data Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprintln (" Found Ġstates Ġ$ states ") ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprintln (" Failed Ġto Ġretrieve Ġstates ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstates Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġstates . toString (). toByteArray () ĊĠĠĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠThe Ġresolve Flow Ġfunction Ġuses Ġreflection Ġto Ġconstruct Ġan Ġinstance Ġof ĠFlow Logic Ġfrom Ġthe Ġgiven Ċ Ġ* Ġflow Ġname Ġand Ġarguments . Ċ Ġ* Ċ Ġ* Ġ@ param Ġflow Name ĠThe Ġname Ġof Ġthe Ġflow Ġprovided Ġby Ġthe Ġremote Ġclient . Ċ Ġ* Ġ@ param Ġflow Args ĠThe Ġlist Ġof Ġarguments Ġfor Ġthe Ġflow Ġprovided Ġby Ġthe Ġremote Ġclient . Ċ Ġ* Ġ@ return ĠReturns Ġan ĠEither Ġwith Ġan Ġinstance Ġof ĠFlow Logic Ġif Ġit Ġwas Ġresol vable , Ġor Ġan ĠError . Ċ Ġ*/ Ċ fun Ġresolve Flow ( flow Name : ĠString , Ġflow Args : ĠList < Any >): ĠEither < Error , ĠFlow Logic < ByteArray >> Ġ= Ġtry Ġ{ ĊĠĠĠ Ġprintln (" At tempting Ġto Ġresolve Ġ$ flow Name Ġto Ġa ĠC ord a Ġflow .") ĊĠĠĠ Ġval Ġkotlin Class Ġ= ĠClass . forName ( flow Name ). kotlin ĊĠĠĠ Ġval Ġctor Ġ= Ġkotlin Class . construct ors . first () ĊĠĠĠ Ġif Ġ( ctor . parameters . size Ġ!= Ġflow Args . size ) Ġ{ ĊĠĠĠĠĠĠĠ Ġprintln (" Flow ĠResolution ĠError : Ġwrong Ġnumber Ġof Ġarguments Ġsupplied .\ n ") ĊĠĠĠĠĠĠĠ ĠLeft ( Error (" Flow ĠResolution ĠError : Ġwrong Ġnumber Ġof Ġarguments Ġsupplied ")) ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠRight ( ctor . call (* flow Args . to Typed Array ()) Ġas ĠFlow Logic < ByteArray >) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprintln (" Flow ĠResolution ĠError : Ġ$ flow Name Ġnot Ġa Ġflow : Ġ${ e . message }. \ n ") ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLeft ( Error (" Flow ĠResolution ĠError : Ġ$ flow Name Ġnot Ġa Ġflow ")) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠ Ġprintln (" Flow ĠResolution ĠError : Ġ${ e . message } Ġ\ n ") ĊĠĠĠ ĠLeft ( Error (" Flow ĠResolution ĠError : Ġ${ e . message } ")) Ċ } Ċ Ċ /** Ċ Ġ* ĠThe Ġcreate View Ġfunction Ġtakes Ġthe Ġdata Ġreturned Ġfrom Ġthe Ġflow Ġas Ġa ĠBase 6 4 Ġencoded Ġstring , Ċ Ġ* Ġthe Ġnode 's Ġsignature Ġon Ġthis Ġdata , Ġand Ġthe Ġnode 's Ġcertificate Ġand Ġassemb les Ġa Ġ[ ViewData ] Ġobject Ġfrom Ċ Ġ* Ġthese , Ġthen Ġassemb les Ġthe Ġ[ State . View ] Ġwith Ġthe Ġrequired Ġmetadata Ġand Ġ[ ViewData ]. Ċ Ġ* Ċ Ġ* Ġ@ param Ġdata ĠThe Ġresult Ġof Ġthe Ġapplication Ġflow Ġthat Ġwas Ġspecified Ġby Ġthe Ġrequesting Ġnetwork . Ċ Ġ* Ġ@ param Ġsignature ĠThe Ġsignature Ġof Ġthe Ġnode Ġsigned Ġon Ġthe Ġdata Ġbyte array Ġas Ġa ĠBase 6 4 Ġstring . Ċ Ġ* Ġ@ param Ġcertificate ĠThe Ġcertificate Ġof Ġthe ĠC ord a Ġnode Ġthat Ġprovided Ġthe Ġsignature . Ċ Ġ* Ġ@ return ĠReturns Ġan ĠEither Ġwith Ġan ĠError Ġif Ġgenerating Ġthe Ġview Ġwas Ġnot Ġsuccessful , Ġor Ġthe Ġ[ State . View ], Ċ Ġ* Ġcontaining Ġthe Ġmetadata , Ġproof Ġand Ġflow Ġresult . Ċ Ġ*/ Ċ fun Ġcreate View ( interop Payload : ĠByteArray , Ġsignature : ĠString , Ġcertificate : ĠString , Ġidentity : ĠString ): ĠEither < Error , ĠState . View > Ġ= Ġtry Ġ{ ĊĠĠĠ Ġprintln (" calling Ġcreate ViewData Ġfunction ") ĊĠĠĠ Ġcreate ViewData ( interop Payload , Ġsignature , Ġcertificate , Ġidentity ). map Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġmeta Ġ= ĠState . Meta . newBuilder () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Protocol ( State . Meta . Protocol . C ORD A ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Timestamp ( Date . from ( Instant . now ()). toString ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Proof Type (" Not ar ization ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Serialization Format (" JSON ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠĠĠĠĠ ĠState . View . newBuilder () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Meta ( meta ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. setData ( ByteString . copyFrom ( it )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠ Ġ} Ċ } Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠ Ġprintln (" Error Ġcreating Ġview : Ġ${ e . message }") ĊĠĠĠ ĠLeft ( Error (" Error Ġcreating Ġview : Ġ${ e . message } ")) Ċ } Ċ Ċ /** Ċ Ġ* ĠThe Ġcreate ViewData Ġfunction Ġassemb les Ġthe Ġdata Ġand Ġproof Ġto Ġbe Ġreturned Ġto Ġthe Ġremote Ġclient . Ċ Ġ* Ċ Ġ* Ġ@ param Ġdata ĠThe Ġdata Ġthat Ġis Ġreturned Ġfrom Ġthe Ġapplication ĠCor D app Ġflow Ġthat Ġis Ġspecified Ġby Ċ Ġ* Ġthe Ġremote Ġclient Ġand Ġtriggered Ġby Ġthe Ġinter op ĠCor D app . Ċ Ġ* Ġ@ param Ġsignature ĠThe Ġsignature Ġof Ġthe Ġnode Ġsigned Ġon Ġthe Ġdata Ġbyte array Ġas Ġa ĠBase 6 4 Ġstring . Ċ Ġ* Ġ@ param Ġcertificate ĠThe Ġcertificate Ġof Ġthe ĠC ord a Ġnode Ġthat Ġprovided Ġthe Ġsignature . Ċ Ġ* Ġ@ return ĠReturns Ġan ĠEither Ġwith Ġthe ĠBase 6 4 - encoded ĠJSON Ġstring Ġof Ġthe Ġ[ ViewData ] Ġobject Ġor Ġan ĠError . Ċ Ġ*/ Ċ fun Ġcreate ViewData ( ĊĠĠĠĠĠĠĠ Ġinter op Payload : ĠByteArray , ĊĠĠĠĠĠĠĠ Ġsignature : ĠString , ĊĠĠĠĠĠĠĠ Ġcertificate : ĠString , ĊĠĠĠĠĠĠĠ Ġidentity : ĠString Ċ ) Ġ: ĠEither < Error , ĠByteArray > Ġ= Ġtry Ġ{ ĊĠĠĠ Ġval Ġnot ar ization Ġ= ĠView Data OuterClass . ViewData . Not ar ization . newBuilder () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Certificate ( certificate ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Signature ( signature ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. setId ( identity ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĊĠĠĠ Ġ// ĠCreate Ġthe Ġview Data Ġobject Ġand Ġconvert Ġto Ġa ĠJSON Ġstring ĊĠĠĠ Ġval Ġview Data Ġ= ĠView Data OuterClass . ViewData . newBuilder () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. addAll Not ar izations ( listOf ( not ar ization )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Payload ( ByteString . copyFrom ( interop Payload )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠ Ġprintln (" View Ġdata Ġcreated : Ġ$ view Data Ġ\ n ") ĊĊĠĠĠ ĠRight ( view Data . toByteArray ()) Ċ } Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠ Ġprintln (" Error Ġcreating Ġdata Ġand Ġproof Ġobject : Ġ${ e . message }\ n ") ĊĠĠĠ ĠLeft ( Error (" Error Ġcreating Ġdata Ġand Ġproof Ġobject : Ġ${ e . message } ")) Ċ }