Skip to content

Commit 8edc753

Browse files
fix(CM): long validation error
1 parent 1bfbdf0 commit 8edc753

File tree

2 files changed

+55
-36
lines changed

2 files changed

+55
-36
lines changed

tidy3d/web/api/webapi.py

Lines changed: 54 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,25 @@
6363
"VOLUME_MESH": "VolumeMesher",
6464
}
6565

66+
TERMINAL_ERRORS = {
67+
"validate_fail",
68+
"error",
69+
"diverged",
70+
"blocked",
71+
"aborting",
72+
"aborted",
73+
}
74+
75+
RUN_STATUSES = [
76+
"draft",
77+
"preprocess",
78+
"validating",
79+
"validate",
80+
"running",
81+
"postprocess",
82+
"success",
83+
]
84+
6685

6786
def _get_url(task_id: str) -> str:
6887
"""Get the URL for a task on our server."""
@@ -1070,21 +1089,13 @@ def _status_to_stage(status: str) -> tuple[str, int]:
10701089

10711090
# Non-verbose path: poll without progress bars then return
10721091
if not verbose:
1073-
terminal_errors = {
1074-
"validate_fail",
1075-
"error",
1076-
"diverged",
1077-
"blocked",
1078-
"aborting",
1079-
"aborted",
1080-
}
10811092
# Run phase
10821093
while True:
10831094
d = _batch_detail(batch_id)
10841095
s = d.totalStatus.value
10851096
total = d.totalTask or 0
10861097
r = d.runSuccess or 0
1087-
if s in terminal_errors:
1098+
if s in TERMINAL_ERRORS:
10881099
raise WebError(f"Batch {batch_id} terminated: {s}")
10891100
if total and r >= total:
10901101
break
@@ -1096,7 +1107,7 @@ def _status_to_stage(status: str) -> tuple[str, int]:
10961107
postprocess_status = d.postprocessStatus
10971108
if postprocess_status == "success":
10981109
break
1099-
elif postprocess_status in terminal_errors:
1110+
elif postprocess_status in TERMINAL_ERRORS:
11001111
raise WebError(
11011112
f"Batch {batch_id} terminated. Please contact customer support and provide this Component Modeler batch ID: '{batch_id}'"
11021113
)
@@ -1110,20 +1121,9 @@ def _status_to_stage(status: str) -> tuple[str, int]:
11101121
TimeElapsedColumn(),
11111122
)
11121123
with Progress(*progress_columns, console=console, transient=False) as progress:
1113-
terminal_errors = {"validate_fail", "error", "diverged", "blocked", "aborting", "aborted"}
1114-
11151124
# Phase: Run (aggregate + per-task)
11161125
p_run = progress.add_task("Run Total", total=1.0)
11171126
task_bars: dict[str, int] = {}
1118-
run_statuses = [
1119-
"draft",
1120-
"preprocess",
1121-
"validating",
1122-
"validate",
1123-
"running",
1124-
"postprocess",
1125-
"success",
1126-
]
11271127

11281128
while True:
11291129
detail = _batch_detail(batch_id)
@@ -1140,8 +1140,8 @@ def _status_to_stage(status: str) -> tuple[str, int]:
11401140
_, idx = _status_to_stage(tstatus)
11411141
pbar = progress.add_task(
11421142
f" {name}",
1143-
total=len(run_statuses) - 1,
1144-
completed=min(idx, len(run_statuses) - 1),
1143+
total=len(RUN_STATUSES) - 1,
1144+
completed=min(idx, len(RUN_STATUSES) - 1),
11451145
)
11461146
task_bars[name] = pbar
11471147

@@ -1174,7 +1174,7 @@ def _status_to_stage(status: str) -> tuple[str, int]:
11741174

11751175
if total and r >= total:
11761176
break
1177-
if status in terminal_errors:
1177+
if status in TERMINAL_ERRORS:
11781178
raise WebError(f"Batch {batch_id} terminated: {status}")
11791179
progress.refresh()
11801180
time.sleep(REFRESH_TIME)
@@ -1195,7 +1195,7 @@ def _status_to_stage(status: str) -> tuple[str, int]:
11951195
progress.update(p_post, completed=0.33)
11961196
elif postprocess_status == "running":
11971197
progress.update(p_post, completed=0.55)
1198-
elif postprocess_status in terminal_errors:
1198+
elif postprocess_status in TERMINAL_ERRORS:
11991199
raise WebError(
12001200
f"Batch {batch_id} terminated. Please contact customer support and provide this Component Modeler batch ID: '{batch_id}'"
12011201
)
@@ -1355,22 +1355,40 @@ def estimate_cost(
13551355
console = get_logging_console() if verbose else None
13561356

13571357
if _is_modeler_batch(task_id):
1358-
status = _batch_detail(task_id).totalStatus.value
1358+
d = _batch_detail(task_id)
1359+
status = d.totalStatus.value
13591360

13601361
# Wait for a termination status
13611362
while status not in ["validate_success", "success", "error", "failed"]:
13621363
time.sleep(REFRESH_TIME)
1363-
status = _batch_detail(task_id).totalStatus.value
1364+
d = _batch_detail(task_id)
1365+
status = d.totalStatus.value
13641366

1365-
if status in ["validate_success", "success"]:
1366-
est_flex_unit = _batch_detail(task_id).estFlexUnit
1367-
if verbose:
1368-
console.log(
1369-
f"Maximum FlexCredit cost: {est_flex_unit:1.3f}. Minimum cost depends on "
1370-
"task execution details. Use 'web.real_cost(task_id)' to get the billed FlexCredit "
1371-
"cost after a simulation run."
1372-
)
1373-
return est_flex_unit
1367+
if status in ["validate_success", "success"]:
1368+
est_flex_unit = _batch_detail(task_id).estFlexUnit
1369+
if verbose:
1370+
console.log(
1371+
f"Maximum FlexCredit cost: {est_flex_unit:1.3f}. Minimum cost depends on "
1372+
"task execution details. Use 'web.real_cost(task_id)' to get the billed FlexCredit "
1373+
"cost after a simulation run."
1374+
)
1375+
return est_flex_unit
1376+
elif status in TERMINAL_ERRORS:
1377+
log.error(f"The ComponentModeler '{task_id}' has failed: {status}")
1378+
1379+
if status == "validate_fail":
1380+
assert d.validateErrors is not None
1381+
for key, error in d.validateErrors.items():
1382+
# I don't like this ideally but would like to control the endpoint to make this better
1383+
error_dict = json.loads(error)
1384+
validation_error = error_dict["validation_error"]
1385+
log.error(
1386+
f"Subtask '{key}' has failed to validate:"
1387+
f" \n {validation_error} \n "
1388+
f"Fix your component modeler configuration. "
1389+
f"Generate subtask simulations locally using `ComponentModelerType.sim_dict`."
1390+
)
1391+
break
13741392
else:
13751393
task = SimulationTask.get(task_id)
13761394

tidy3d/web/core/task_info.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,3 +316,4 @@ class BatchDetail(TaskBase):
316316
totalCheckMillis: int = None
317317
message: str = None
318318
tasks: list[BatchMember] = []
319+
validateErrors: dict = None

0 commit comments

Comments
 (0)