4
4
import static io .temporal .internal .common .NexusUtil .nexusProtoLinkToLink ;
5
5
6
6
import com .uber .m3 .tally .Scope ;
7
+ import io .grpc .StatusRuntimeException ;
7
8
import io .nexusrpc .Header ;
8
9
import io .nexusrpc .OperationException ;
9
10
import io .nexusrpc .handler .*;
12
13
import io .temporal .api .nexus .v1 .*;
13
14
import io .temporal .client .WorkflowClient ;
14
15
import io .temporal .client .WorkflowException ;
16
+ import io .temporal .client .WorkflowNotFoundException ;
15
17
import io .temporal .common .converter .DataConverter ;
16
18
import io .temporal .common .interceptors .WorkerInterceptor ;
17
19
import io .temporal .failure .ApplicationFailure ;
@@ -203,6 +205,9 @@ private CancelOperationResponse handleCancelledOperation(
203
205
private void convertKnownFailures (Throwable e ) {
204
206
Throwable failure = CheckedExceptionWrapper .unwrap (e );
205
207
if (failure instanceof WorkflowException ) {
208
+ if (failure instanceof WorkflowNotFoundException ) {
209
+ throw new HandlerException (HandlerException .ErrorType .NOT_FOUND , failure );
210
+ }
206
211
throw new HandlerException (HandlerException .ErrorType .BAD_REQUEST , failure );
207
212
}
208
213
if (failure instanceof ApplicationFailure ) {
@@ -213,6 +218,10 @@ private void convertKnownFailures(Throwable e) {
213
218
HandlerException .RetryBehavior .NON_RETRYABLE );
214
219
}
215
220
}
221
+ if (failure instanceof StatusRuntimeException ) {
222
+ StatusRuntimeException statusRuntimeException = (StatusRuntimeException ) failure ;
223
+ throw convertStatusRuntimeExceptionToHandlerException (statusRuntimeException );
224
+ }
216
225
if (failure instanceof Error ) {
217
226
throw (Error ) failure ;
218
227
}
@@ -221,6 +230,45 @@ private void convertKnownFailures(Throwable e) {
221
230
: new RuntimeException (failure );
222
231
}
223
232
233
+ private HandlerException convertStatusRuntimeExceptionToHandlerException (
234
+ StatusRuntimeException sre ) {
235
+ switch (sre .getStatus ().getCode ()) {
236
+ case INVALID_ARGUMENT :
237
+ return new HandlerException (HandlerException .ErrorType .BAD_REQUEST , sre );
238
+ case ALREADY_EXISTS :
239
+ case FAILED_PRECONDITION :
240
+ case OUT_OF_RANGE :
241
+ return new HandlerException (
242
+ HandlerException .ErrorType .INTERNAL , sre , HandlerException .RetryBehavior .NON_RETRYABLE );
243
+ case ABORTED :
244
+ case UNAVAILABLE :
245
+ return new HandlerException (HandlerException .ErrorType .UNAVAILABLE , sre );
246
+ case CANCELLED :
247
+ case DATA_LOSS :
248
+ case INTERNAL :
249
+ case UNKNOWN :
250
+ case UNAUTHENTICATED :
251
+ case PERMISSION_DENIED :
252
+ // Note that codes.Unauthenticated, codes.PermissionDenied have Nexus error types but we
253
+ // convert to internal
254
+ // because this is not a client auth error and happens when the handler fails to auth with
255
+ // Temporal and should
256
+ // be considered retryable.
257
+ return new HandlerException (HandlerException .ErrorType .INTERNAL , sre );
258
+ case NOT_FOUND :
259
+ return new HandlerException (HandlerException .ErrorType .NOT_FOUND , sre );
260
+ case RESOURCE_EXHAUSTED :
261
+ return new HandlerException (HandlerException .ErrorType .RESOURCE_EXHAUSTED , sre );
262
+ case UNIMPLEMENTED :
263
+ return new HandlerException (HandlerException .ErrorType .NOT_IMPLEMENTED , sre );
264
+ case DEADLINE_EXCEEDED :
265
+ return new HandlerException (HandlerException .ErrorType .UPSTREAM_TIMEOUT , sre );
266
+ default :
267
+ // If the status code is not recognized, we treat it as an internal error
268
+ return new HandlerException (HandlerException .ErrorType .INTERNAL , sre );
269
+ }
270
+ }
271
+
224
272
private OperationStartResult <HandlerResultContent > startOperation (
225
273
OperationContext context , OperationStartDetails details , HandlerInputContent input )
226
274
throws OperationException {
0 commit comments