Build the response for a worker that crashed/hung/failed without producing a * result. The crash is already contained (this process survived); we report it * rather than dying. Precise skip-and-continue (quarantine the culprit, index the * rest) is layered on in the probe stage. */
| 3473 | * rather than dying. Precise skip-and-continue (quarantine the culprit, index the |
| 3474 | * rest) is layered on in the probe stage. */ |
| 3475 | static char *build_worker_failure_response(const char *args, cbm_proc_outcome_t outcome) { |
| 3476 | char *repo_path = cbm_mcp_get_string_arg(args, "repo_path"); |
| 3477 | yyjson_mut_doc *doc = yyjson_mut_doc_new(NULL); |
| 3478 | yyjson_mut_val *root = yyjson_mut_obj(doc); |
| 3479 | yyjson_mut_doc_set_root(doc, root); |
| 3480 | yyjson_mut_obj_add_str(doc, root, "status", "error"); |
| 3481 | yyjson_mut_obj_add_str(doc, root, "outcome", cbm_proc_outcome_str(outcome)); |
| 3482 | yyjson_mut_obj_add_str( |
| 3483 | doc, root, "hint", |
| 3484 | outcome == CBM_PROC_HANG |
| 3485 | ? "Indexing worker timed out (a file made no progress). The worker was " |
| 3486 | "terminated and the server survived. Re-run to retry." |
| 3487 | : "Indexing worker crashed on a file. The crash was contained (the server " |
| 3488 | "survived). Re-run to retry; a future release isolates the culprit file."); |
| 3489 | if (repo_path) { |
| 3490 | yyjson_mut_obj_add_strcpy(doc, root, "repo_path", repo_path); |
| 3491 | } |
| 3492 | char *json = yy_doc_to_str(doc); |
| 3493 | yyjson_mut_doc_free(doc); |
| 3494 | free(repo_path); |
| 3495 | char *result = cbm_mcp_text_result(json, true); |
| 3496 | free(json); |
| 3497 | return result; |
| 3498 | } |
| 3499 | |
| 3500 | /* Drop the cached store so the next query reopens whatever the worker wrote (each |
| 3501 | * worker is a fresh process that deletes + recreates the .db). NULL-safe: the |
no test coverage detected