Skip to content

Commit 7b2a0c7

Browse files
Update Nexus failure conversion
1 parent d3d7e09 commit 7b2a0c7

2 files changed

Lines changed: 76 additions & 26 deletions

File tree

temporal-sdk/src/main/java/io/temporal/internal/common/NexusUtil.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,11 @@ public static io.temporal.api.failure.v1.Failure nexusFailureToAPIFailure(
8282
if (failureInfo.getMetadata().containsKey("type")
8383
&& failureInfo.getMetadata().get("type").equals(TEMPORAL_FAILURE_TYPE_STRING)) {
8484
// Details contains a JSON-serialized Temporal failure
85-
try {
86-
JsonFormat.parser().ignoringUnknownFields().merge(failureInfo.getDetailsJson(), apiFailure);
87-
} catch (InvalidProtocolBufferException e) {
88-
throw new RuntimeException(e);
89-
}
85+
try {
86+
JsonFormat.parser().ignoringUnknownFields().merge(failureInfo.getDetailsJson(), apiFailure);
87+
} catch (InvalidProtocolBufferException e) {
88+
throw new RuntimeException(e);
89+
}
9090
} else {
9191
// Create an ApplicationFailure with the Nexus failure data
9292
io.temporal.api.common.v1.Payloads payloads = nexusFailureMetadataToPayloads(failureInfo);
@@ -102,9 +102,9 @@ public static io.temporal.api.failure.v1.Failure nexusFailureToAPIFailure(
102102

103103
// Ensure these always get written
104104
apiFailure.setMessage(failureInfo.getMessage());
105-
// if (!failureInfo.getStackTrace().isEmpty()) {
106-
// apiFailure.setStackTrace(failureInfo.getStackTrace());
107-
// }
105+
if (!failureInfo.getStackTrace().isEmpty()) {
106+
apiFailure.setStackTrace(failureInfo.getStackTrace());
107+
}
108108

109109
return apiFailure.build();
110110
}

temporal-sdk/src/test/java/io/temporal/workflow/nexus/OperationFailMetricTest.java

Lines changed: 68 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ public class OperationFailMetricTest {
4242
SDKTestWorkflowRule.newBuilder()
4343
.setWorkflowTypes(TestNexus.class)
4444
.setNexusServiceImplementation(new TestNexusServiceImpl())
45+
.setUseExternalService(ENABLE_NEW_ASSERTS)
4546
.setMetricsScope(
4647
new RootScopeBuilder()
4748
.reporter(reporter)
@@ -149,6 +150,14 @@ public void failOperationApplicationErrorMetrics() {
149150
assertNoRetries("fail-app");
150151
ApplicationFailure applicationFailure =
151152
assertNexusOperationFailure(ApplicationFailure.class, workflowException);
153+
if (ENABLE_NEW_ASSERTS) {
154+
Assert.assertEquals(
155+
"message='intentional failure', type='TestFailure', nonRetryable=false",
156+
applicationFailure.getOriginalMessage());
157+
Assert.assertEquals("OperationError", applicationFailure.getType());
158+
Assert.assertNotNull(applicationFailure.getCause());
159+
applicationFailure = (ApplicationFailure) applicationFailure.getCause();
160+
}
152161
Assert.assertEquals("intentional failure", applicationFailure.getOriginalMessage());
153162
Assert.assertEquals("TestFailure", applicationFailure.getType());
154163
Assert.assertEquals("foo", applicationFailure.getDetails().get(String.class));
@@ -179,21 +188,22 @@ public void cancelOperationApplicationErrorMetrics() {
179188
assertNoRetries("cancel-app");
180189
CanceledFailure canceledFailure =
181190
assertNexusOperationFailure(CanceledFailure.class, workflowException);
182-
// Assert.assertEquals("intentional cancel", canceledFailure.getOriginalMessage());
183-
Assert.assertEquals(
184-
"message='intentional cancel', type='TestFailure', nonRetryable=false",
185-
canceledFailure.getOriginalMessage());
186-
// TODO assert stack trace
187-
// Old assertions
188-
// Assert.assertEquals("foo", canceledFailure.getDetails());
189-
// New assertions
190-
Assert.assertEquals(0, canceledFailure.getDetails().getSize());
191-
Assert.assertNotNull(canceledFailure.getCause());
192-
Assert.assertTrue(canceledFailure.getCause() instanceof ApplicationFailure);
193-
ApplicationFailure applicationFailure = (ApplicationFailure) canceledFailure.getCause();
194-
Assert.assertEquals("TestFailure", applicationFailure.getType());
195-
Assert.assertEquals("intentional cancel", applicationFailure.getOriginalMessage());
196-
Assert.assertEquals("foo", applicationFailure.getDetails().get(String.class));
191+
//
192+
if (ENABLE_NEW_ASSERTS) {
193+
Assert.assertEquals(
194+
"message='intentional cancel', type='TestFailure', nonRetryable=false",
195+
canceledFailure.getOriginalMessage());
196+
Assert.assertEquals(0, canceledFailure.getDetails().getSize());
197+
Assert.assertNotNull(canceledFailure.getCause());
198+
Assert.assertTrue(canceledFailure.getCause() instanceof ApplicationFailure);
199+
ApplicationFailure applicationFailure = (ApplicationFailure) canceledFailure.getCause();
200+
Assert.assertEquals("TestFailure", applicationFailure.getType());
201+
Assert.assertEquals("intentional cancel", applicationFailure.getOriginalMessage());
202+
Assert.assertEquals("foo", applicationFailure.getDetails().get(String.class));
203+
} else {
204+
Assert.assertEquals("intentional cancel", canceledFailure.getOriginalMessage());
205+
Assert.assertEquals(1, canceledFailure.getDetails().getSize());
206+
}
197207

198208
Map<String, String> execFailedTags =
199209
getOperationTags()
@@ -223,9 +233,11 @@ public void failOperationMessageApplicationErrorMetrics() {
223233
assertNoRetries("fail-msg-app");
224234
ApplicationFailure applicationFailure =
225235
assertNexusOperationFailure(ApplicationFailure.class, workflowException);
226-
Assert.assertEquals("failure message", applicationFailure.getOriginalMessage());
227-
Assert.assertEquals("OperationError", applicationFailure.getType());
228-
applicationFailure = (ApplicationFailure) applicationFailure.getCause();
236+
if (ENABLE_NEW_ASSERTS) {
237+
Assert.assertEquals("failure message", applicationFailure.getOriginalMessage());
238+
Assert.assertEquals("OperationError", applicationFailure.getType());
239+
applicationFailure = (ApplicationFailure) applicationFailure.getCause();
240+
}
229241
Assert.assertEquals("intentional failure", applicationFailure.getOriginalMessage());
230242
Assert.assertEquals("TestFailure", applicationFailure.getType());
231243
Assert.assertEquals("foo", applicationFailure.getDetails().get(String.class));
@@ -277,6 +289,39 @@ public void failHandlerBadRequestMetrics() {
277289
});
278290
}
279291

292+
@Test
293+
public void failHandlerBadRequestNoCauseMetrics() {
294+
TestWorkflow1 workflowStub =
295+
testWorkflowRule.newWorkflowStubTimeoutOptions(TestWorkflow1.class);
296+
WorkflowFailedException workflowException =
297+
Assert.assertThrows(
298+
WorkflowFailedException.class, () -> workflowStub.execute("handlererror-no-cause"));
299+
assertNoRetries("handlererror-no-cause");
300+
HandlerException handlerException =
301+
assertNexusOperationFailure(HandlerException.class, workflowException);
302+
Assert.assertEquals(HandlerException.ErrorType.BAD_REQUEST, handlerException.getErrorType());
303+
if (ENABLE_NEW_ASSERTS) {
304+
Assert.assertEquals("handler failure message", handlerException.getMessage());
305+
Assert.assertNull(handlerException.getCause());
306+
}
307+
308+
Map<String, String> execFailedTags =
309+
getOperationTags()
310+
.put(MetricsTag.TASK_FAILURE_TYPE, "handler_error_BAD_REQUEST")
311+
.buildKeepingLast();
312+
Eventually.assertEventually(
313+
Duration.ofSeconds(3),
314+
() -> {
315+
reporter.assertTimer(
316+
MetricsType.NEXUS_SCHEDULE_TO_START_LATENCY, getBaseTags().buildKeepingLast());
317+
reporter.assertTimer(
318+
MetricsType.NEXUS_EXEC_LATENCY, getOperationTags().buildKeepingLast());
319+
reporter.assertTimer(
320+
MetricsType.NEXUS_TASK_E2E_LATENCY, getOperationTags().buildKeepingLast());
321+
reporter.assertCounter(MetricsType.NEXUS_EXEC_FAILED_COUNTER, execFailedTags, 1);
322+
});
323+
}
324+
280325
@Test
281326
public void failHandlerAppBadRequestMetrics() {
282327
TestWorkflow1 workflowStub =
@@ -588,6 +633,11 @@ public OperationHandler<String, String> operation() {
588633
HandlerException.ErrorType.INTERNAL,
589634
ApplicationFailure.newNonRetryableFailure("intentional failure", "TestFailure"),
590635
HandlerException.RetryBehavior.NON_RETRYABLE);
636+
case "handlererror-no-cause":
637+
throw new HandlerException(
638+
HandlerException.ErrorType.BAD_REQUEST,
639+
"handler failure message",
640+
(Throwable) null);
591641
case "already-started":
592642
throw new WorkflowExecutionAlreadyStarted(
593643
WorkflowExecution.getDefaultInstance(), "TestWorkflowType", null);

0 commit comments

Comments
 (0)