2
2
import uuid
3
3
from dataclasses import dataclass
4
4
from enum import IntEnum
5
+ from itertools import zip_longest
5
6
from typing import Any , Callable , Literal , Union
6
7
7
8
import nexusrpc
@@ -1164,12 +1165,34 @@ async def assert_handler_workflow_has_link_to_caller_workflow(
1164
1165
# io.temporal.failure.ApplicationFailure(type=no-type-attr, message=message='application error 1', type='APPLICATION_ERROR', nonRetryable=true)
1165
1166
# io.temporal.failure.ApplicationFailure(type=no-type-attr, message=message='Custom error 2', type='io.temporal.samples.nexus.handler.NexusServiceImpl$MyCustomException', nonRetryable=false)
1166
1167
1168
+ ActionInSyncOp = Literal [
1169
+ "application_error_non_retryable" ,
1170
+ "custom_error" ,
1171
+ "custom_error_from_custom_error" ,
1172
+ "application_error_non_retryable_from_custom_error" ,
1173
+ "nexus_handler_error_not_found" ,
1174
+ "nexus_handler_error_not_found_from_custom_error" ,
1175
+ "nexus_operation_error_from_application_error_non_retryable_from_custom_error" ,
1176
+ ]
1177
+
1167
1178
1168
1179
@dataclass
1169
1180
class ErrorConversionTestCase :
1170
- name : str
1181
+ name : ActionInSyncOp
1171
1182
java_behavior : list [tuple [type [Exception ], dict [str , Any ]]]
1172
1183
1184
+ @staticmethod
1185
+ def parse_exception (
1186
+ exception : BaseException ,
1187
+ ) -> tuple [type [BaseException ], dict [str , Any ]]:
1188
+ if isinstance (exception , NexusOperationError ):
1189
+ return NexusOperationError , {}
1190
+ return type (exception ), {
1191
+ "message" : getattr (exception , "message" , None ),
1192
+ "type" : getattr (exception , "type" , None ),
1193
+ "non_retryable" : getattr (exception , "non_retryable" , None ),
1194
+ }
1195
+
1173
1196
1174
1197
error_conversion_test_cases = []
1175
1198
@@ -1247,6 +1270,13 @@ class ErrorConversionTestCase:
1247
1270
_ = ["NexusOperationError" , "HandlerError" ]
1248
1271
# Java
1249
1272
# [Not possible]
1273
+ error_conversion_test_cases .append (
1274
+ ErrorConversionTestCase (
1275
+ name = "custom_error_from_custom_error" ,
1276
+ java_behavior = [], # [Not possible]
1277
+ )
1278
+ )
1279
+
1250
1280
1251
1281
# application_error_non_retryable_from_custom_error:
1252
1282
_ = ["NexusOperationError" , "HandlerError" ]
@@ -1302,7 +1332,7 @@ class ErrorConversionTestCase:
1302
1332
1303
1333
error_conversion_test_cases .append (
1304
1334
ErrorConversionTestCase (
1305
- name = "application_error_non_retryable_from_custom_error " ,
1335
+ name = "nexus_handler_error_not_found " ,
1306
1336
java_behavior = [
1307
1337
(NexusOperationError , {}),
1308
1338
(
@@ -1331,7 +1361,7 @@ class ErrorConversionTestCase:
1331
1361
# [Not possible]
1332
1362
error_conversion_test_cases .append (
1333
1363
ErrorConversionTestCase (
1334
- name = "nexus_handler_error_not_found " ,
1364
+ name = "nexus_handler_error_not_found_from_custom_error " ,
1335
1365
java_behavior = [], # [Not possible]
1336
1366
)
1337
1367
)
@@ -1371,17 +1401,6 @@ class ErrorConversionTestCase:
1371
1401
)
1372
1402
1373
1403
1374
- ActionInSyncOp = Literal [
1375
- "application_error_non_retryable" ,
1376
- "custom_error" ,
1377
- "custom_error_from_custom_error" ,
1378
- "application_error_non_retryable_from_custom_error" ,
1379
- "nexus_handler_error_not_found" ,
1380
- "nexus_handler_error_not_found_from_custom_error" ,
1381
- "nexus_operation_error_from_application_error_non_retryable_from_custom_error" ,
1382
- ]
1383
-
1384
-
1385
1404
class CustomError (Exception ):
1386
1405
pass
1387
1406
@@ -1453,9 +1472,10 @@ def __init__(self, input: ErrorTestInput):
1453
1472
service = ErrorTestService ,
1454
1473
endpoint = make_nexus_endpoint_name (input .task_queue ),
1455
1474
)
1475
+ self .test_cases = {t .name : t for t in error_conversion_test_cases }
1456
1476
1457
1477
@workflow .run
1458
- async def run (self , input : ErrorTestInput ) -> list [ str ] :
1478
+ async def run (self , input : ErrorTestInput ) -> None :
1459
1479
try :
1460
1480
await self .nexus_client .execute_operation (
1461
1481
# TODO(nexus-preview): why wasn't this a type error?
@@ -1470,7 +1490,26 @@ async def run(self, input: ErrorTestInput) -> list[str]:
1470
1490
while err .__cause__ :
1471
1491
errs .append (err .__cause__ )
1472
1492
err = err .__cause__
1473
- return [type (err ).__name__ for err in errs ]
1493
+ actual = [ErrorConversionTestCase .parse_exception (err ) for err in errs ]
1494
+ results = list (
1495
+ zip_longest (
1496
+ self .test_cases [input .action_in_sync_op ].java_behavior ,
1497
+ actual ,
1498
+ fillvalue = None ,
1499
+ )
1500
+ )
1501
+ print (f"""
1502
+
1503
+ { input .action_in_sync_op }
1504
+ { '-' * 80 }
1505
+ """ )
1506
+ for java_behavior , actual in results :
1507
+ print (f"Java: { java_behavior } " )
1508
+ print (f"Python: { actual } " )
1509
+ print ()
1510
+ print ("-" * 80 )
1511
+ return None
1512
+
1474
1513
assert False , "Unreachable"
1475
1514
1476
1515
@@ -1497,7 +1536,7 @@ async def test_errors_raised_by_nexus_operation(
1497
1536
task_queue = task_queue ,
1498
1537
):
1499
1538
await create_nexus_endpoint (task_queue , client )
1500
- result = await client .execute_workflow (
1539
+ await client .execute_workflow (
1501
1540
ErrorTestCallerWorkflow .run ,
1502
1541
ErrorTestInput (
1503
1542
task_queue = task_queue ,
@@ -1506,5 +1545,3 @@ async def test_errors_raised_by_nexus_operation(
1506
1545
id = str (uuid .uuid4 ()),
1507
1546
task_queue = task_queue ,
1508
1547
)
1509
-
1510
- print (f"\n \n \n { action_in_sync_op } : \n " , result , "\n \n \n " )
0 commit comments