further enhanced error handling + added retries in case of parallel writes

This commit is contained in:
2026-06-03 17:27:51 +02:00
parent d0daa7e937
commit fc84d55bd6
21 changed files with 184 additions and 383 deletions

View File

@ -40,15 +40,7 @@ case 'GET':
qdb_discard($tmpDb, $lockFp);
json_success(['questionnaires' => $rows, 'categoryKeys' => $categoryKeys]);
} catch (Throwable $e) {
if (isset($tmpDb, $lockFp)) {
qdb_discard($tmpDb, $lockFp);
}
if (function_exists('qdb_api_log_note_exception')) {
qdb_api_log_note_exception($e);
}
require_once __DIR__ . '/../lib/errors.php';
error_log('questionnaires GET: ' . $e->getMessage());
json_error('SERVER_ERROR', qdb_public_error_message($e, 'Load questionnaires'), 500);
qdb_handler_fail($e, 'Load questionnaires', null, $tmpDb ?? null, $lockFp ?? null);
}
break;
@ -59,7 +51,7 @@ case 'POST':
if (($body['action'] ?? '') === 'updateConditionMessageLabel') {
$messageKey = trim((string)($body['messageKey'] ?? ''));
$germanLabel = (string)($body['germanLabel'] ?? '');
[$pdo, $tmpDb, $lockFp] = qdb_open(true);
[$pdo, $tmpDb, $lockFp] = qdb_open_write_or_fail();
try {
qdb_set_app_string_german_label($pdo, $messageKey, $germanLabel);
qdb_save($tmpDb, $lockFp);
@ -68,9 +60,7 @@ case 'POST':
'germanLabel' => trim($germanLabel),
]);
} catch (Throwable $e) {
qdb_discard($tmpDb, $lockFp);
error_log('updateConditionMessageLabel: ' . $e->getMessage());
json_error('SERVER_ERROR', 'Server error', 500);
qdb_handler_fail($e, 'Update condition message label', null, $tmpDb, $lockFp);
}
break;
}
@ -78,7 +68,7 @@ case 'POST':
if (($body['action'] ?? '') === 'updateCategoryLabel') {
$categoryKey = trim((string)($body['categoryKey'] ?? ''));
$germanLabel = (string)($body['germanLabel'] ?? '');
[$pdo, $tmpDb, $lockFp] = qdb_open(true);
[$pdo, $tmpDb, $lockFp] = qdb_open_write_or_fail();
try {
$stringKey = qdb_set_category_german_label($pdo, $categoryKey, $germanLabel);
qdb_save($tmpDb, $lockFp);
@ -88,9 +78,7 @@ case 'POST':
'germanLabel' => trim($germanLabel),
]);
} catch (Throwable $e) {
qdb_discard($tmpDb, $lockFp);
error_log('updateCategoryLabel: ' . $e->getMessage());
json_error('SERVER_ERROR', 'Server error', 500);
qdb_handler_fail($e, 'Update category label', null, $tmpDb, $lockFp);
}
break;
}
@ -100,15 +88,13 @@ case 'POST':
if ($categoryKey === '') {
json_error('INVALID_FIELD', 'categoryKey is required', 400);
}
[$pdo, $tmpDb, $lockFp] = qdb_open(true);
[$pdo, $tmpDb, $lockFp] = qdb_open_write_or_fail();
try {
$cleared = qdb_delete_category_key($pdo, $categoryKey);
qdb_save($tmpDb, $lockFp);
json_success(['deleted' => $categoryKey, 'questionnairesCleared' => $cleared]);
} catch (Throwable $e) {
qdb_discard($tmpDb, $lockFp);
error_log('deleteCategoryKey: ' . $e->getMessage());
json_error('SERVER_ERROR', 'Server error', 500);
qdb_handler_fail($e, 'Delete category key', null, $tmpDb, $lockFp);
}
break;
}
@ -119,7 +105,7 @@ case 'POST':
json_error('MISSING_FIELDS', 'bundle object is required', 400);
}
$replaceIfExists = !empty($body['replaceIfExists']);
[$pdo, $tmpDb, $lockFp] = qdb_open(true);
[$pdo, $tmpDb, $lockFp] = qdb_open_write_or_fail();
try {
$pdo->exec('PRAGMA foreign_keys = OFF;');
$result = qdb_import_questionnaires_bundle($pdo, $bundle, $replaceIfExists);
@ -127,14 +113,7 @@ case 'POST':
qdb_save($tmpDb, $lockFp);
json_success($result);
} catch (Throwable $e) {
qdb_discard($tmpDb, $lockFp);
error_log('importBundle: ' . $e->getMessage());
require_once __DIR__ . '/../lib/errors.php';
if (function_exists('qdb_api_log_note_exception')) {
qdb_api_log_note_exception($e);
}
error_log('importBundle: ' . $e->getMessage());
json_error('SERVER_ERROR', qdb_public_error_message($e, 'Import'), 500);
qdb_handler_fail($e, 'Import questionnaires', null, $tmpDb, $lockFp);
}
break;
}
@ -150,7 +129,7 @@ case 'POST':
$showPts = (int)($body['showPoints'] ?? 0);
$condJson = $body['conditionJson'] ?? '{}';
[$pdo, $tmpDb, $lockFp] = qdb_open(true);
[$pdo, $tmpDb, $lockFp] = qdb_open_write_or_fail();
try {
if ($order === 0) {
$order = (int)$pdo->query("SELECT COALESCE(MAX(orderIndex),0)+1 FROM questionnaire")->fetchColumn();
@ -170,9 +149,7 @@ case 'POST':
'conditionJson' => $condJson, 'questionCount' => 0,
]]);
} catch (Throwable $e) {
qdb_discard($tmpDb, $lockFp);
error_log($e->getMessage());
json_error('SERVER_ERROR', 'Server error', 500);
qdb_handler_fail($e, 'Create questionnaire', null, $tmpDb, $lockFp);
}
break;
@ -184,7 +161,7 @@ case 'PUT':
}
$id = $body['questionnaireID'];
[$pdo, $tmpDb, $lockFp] = qdb_open(true);
[$pdo, $tmpDb, $lockFp] = qdb_open_write_or_fail();
try {
$existing = $pdo->prepare('SELECT * FROM questionnaire WHERE questionnaireID = :id');
$existing->execute([':id' => $id]);
@ -217,9 +194,7 @@ case 'PUT':
'orderIndex' => $order, 'showPoints' => $showPts, 'conditionJson' => $condJson,
]]);
} catch (Throwable $e) {
qdb_discard($tmpDb, $lockFp);
error_log($e->getMessage());
json_error('SERVER_ERROR', 'Server error', 500);
qdb_handler_fail($e, 'Update questionnaire', null, $tmpDb, $lockFp);
}
break;
@ -231,7 +206,7 @@ case 'DELETE':
}
$id = $body['questionnaireID'];
[$pdo, $tmpDb, $lockFp] = qdb_open(true);
[$pdo, $tmpDb, $lockFp] = qdb_open_write_or_fail();
try {
$pdo->exec('PRAGMA foreign_keys = OFF;');
$pdo->beginTransaction();
@ -260,12 +235,7 @@ case 'DELETE':
qdb_save($tmpDb, $lockFp);
json_success([]);
} catch (Throwable $e) {
if ($pdo->inTransaction()) {
$pdo->rollBack();
}
qdb_discard($tmpDb, $lockFp);
error_log($e->getMessage());
json_error('SERVER_ERROR', 'Server error', 500);
qdb_handler_fail($e, 'Delete questionnaire', $pdo, $tmpDb, $lockFp);
}
break;