1010import io .grpc .Metadata .Key ;
1111import io .grpc .Status ;
1212import io .grpc .StatusException ;
13+ import io .grpc .StatusRuntimeException ;
1314import java .util .Map ;
1415import java .util .Optional ;
1516import java .util .Set ;
1617import org .junit .jupiter .api .Test ;
18+ import org .junit .jupiter .api .extension .ExtendWith ;
19+ import org .mockito .junit .jupiter .MockitoExtension ;
1720
21+ @ ExtendWith (MockitoExtension .class )
1822class ContextualExceptionDetailsTest {
1923 static final String TEST_REQUEST_ID = "example-request-id" ;
2024 static final String TEST_TENANT = "example-tenant" ;
@@ -86,7 +90,8 @@ void parsesMetadataWithoutMessage() {
8690 @ Test
8791 void parsesMetadataWithMessage () {
8892 assertEquals (
89- Optional .of (new ContextualExceptionDetails (TEST_CONTEXT , "test message" )),
93+ Optional .of (
94+ new ContextualExceptionDetails (TEST_CONTEXT ).withExternalMessage ("test message" )),
9095 ContextualExceptionDetails .fromMetadata (
9196 metadataFromMap (
9297 Map .of (
@@ -98,6 +103,44 @@ void parsesMetadataWithMessage() {
98103 "test message" ))));
99104 }
100105
106+ @ Test
107+ void buildsFromExistingException () {
108+ StatusRuntimeException exception =
109+ ContextualStatusExceptionBuilder .from (
110+ Status .INVALID_ARGUMENT
111+ .withDescription ("test message" )
112+ .asException (TEST_CONTEXT .buildTrailers ()))
113+ .useStatusDescriptionAsExternalMessage ()
114+ .buildRuntimeException ();
115+
116+ assertEquals (
117+ Set .of (REQUEST_ID_HEADER_KEY , TENANT_ID_HEADER_KEY , EXTERNAL_MESSAGE_KEY .originalName ()),
118+ exception .getTrailers ().keys ());
119+ assertEquals (TEST_CONTEXT , RequestContext .fromMetadata (exception .getTrailers ()));
120+ assertEquals ("test message" , exception .getTrailers ().get (EXTERNAL_MESSAGE_KEY ));
121+ }
122+
123+ @ Test
124+ void buildsFromExceptionWithCustomTrailers () {
125+ Key <String > customKey = Key .of ("test" , ASCII_STRING_MARSHALLER );
126+ Metadata customMetadata = new Metadata ();
127+ customMetadata .put (customKey , "test-value" );
128+ customMetadata .put (EXTERNAL_MESSAGE_KEY , "should be ignored" );
129+ StatusException exception =
130+ ContextualStatusExceptionBuilder .from (
131+ Status .INVALID_ARGUMENT
132+ .withDescription ("test message" )
133+ .asRuntimeException (customMetadata ))
134+ .withExternalMessage ("custom message" )
135+ .buildCheckedException ();
136+
137+ assertEquals (
138+ Set .of (customKey .originalName (), EXTERNAL_MESSAGE_KEY .originalName ()),
139+ exception .getTrailers ().keys ());
140+ assertEquals ("custom message" , exception .getTrailers ().get (EXTERNAL_MESSAGE_KEY ));
141+ assertEquals ("test-value" , exception .getTrailers ().get (customKey ));
142+ }
143+
101144 Metadata metadataFromMap (Map <String , String > metadataMap ) {
102145 Metadata metadata = new Metadata ();
103146 metadataMap .forEach ((key , value ) -> metadata .put (Key .of (key , ASCII_STRING_MARSHALLER ), value ));
0 commit comments