Улучшена обработка ошибок API

Бэкенд:
- Добавлен try-catch для insert, update, delete, delete-batch
- Ошибки возвращаются как JSON с полем message

Фронтенд:
- Улучшена функция api() для парсинга JSON ошибок
- Извлечение понятного сообщения из ответа сервера

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Mikhail Chusavitin
2026-01-22 11:41:39 +03:00
parent 23e557d792
commit 0700fcd584
2 changed files with 94 additions and 47 deletions

View File

@@ -18,11 +18,34 @@ async function api(url, method = 'GET', body) {
if (body) opts.body = JSON.stringify(body);
const res = await fetch(url, opts);
if (!res.ok) {
// Пытаемся распарсить как JSON
const contentType = res.headers.get('content-type');
let data;
if (contentType && contentType.includes('application/json')) {
data = await res.json();
} else {
const txt = await res.text();
throw new Error(`HTTP ${res.status}: ${txt}`);
// Пытаемся извлечь сообщение из HTML ошибки Slim
const msgMatch = txt.match(/<strong>Message:<\/strong>\s*([^<]+)/);
if (msgMatch) {
throw new Error(msgMatch[1].trim());
}
throw new Error(`Ошибка сервера: ${res.status}`);
}
return res.json();
if (!res.ok) {
// Сервер вернул JSON с ошибкой
throw new Error(data.message || data.error || 'Неизвестная ошибка');
}
// Проверяем на ошибку в успешном ответе
if (data.error) {
throw new Error(data.message || 'Ошибка');
}
return data;
}
function updateSelectionCounter() {

View File

@@ -123,51 +123,69 @@ $app->post('/api/table/data', function (Request $request, Response $response) us
// API: insert / update / delete
$app->post('/api/table/insert', function (Request $request, Response $response) use ($container) {
$payload = json_decode((string)$request->getBody(), true);
$pdo = $container->get('db');
$meta = new \App\MetaService($pdo);
$ds = new \App\DataService($pdo);
try {
$payload = json_decode((string)$request->getBody(), true);
$pdo = $container->get('db');
$meta = new \App\MetaService($pdo);
$ds = new \App\DataService($pdo);
$schema = $payload['schema'];
$table = $payload['table'];
$row = $payload['row'];
$metaArr = $meta->getTableMeta($schema, $table);
$schema = $payload['schema'];
$table = $payload['table'];
$row = $payload['row'];
$metaArr = $meta->getTableMeta($schema, $table);
$result = $ds->insertRow($schema, $table, $row, $metaArr['columns']);
$response->getBody()->write(json_encode($result));
return $response->withHeader('Content-Type', 'application/json');
$result = $ds->insertRow($schema, $table, $row, $metaArr['columns']);
$response->getBody()->write(json_encode($result));
return $response->withHeader('Content-Type', 'application/json');
} catch (\Exception $e) {
$error = ['error' => true, 'message' => $e->getMessage()];
$response->getBody()->write(json_encode($error));
return $response->withHeader('Content-Type', 'application/json')->withStatus(400);
}
});
$app->post('/api/table/update', function (Request $request, Response $response) use ($container) {
$payload = json_decode((string)$request->getBody(), true);
$pdo = $container->get('db');
$meta = new \App\MetaService($pdo);
$ds = new \App\DataService($pdo);
try {
$payload = json_decode((string)$request->getBody(), true);
$pdo = $container->get('db');
$meta = new \App\MetaService($pdo);
$ds = new \App\DataService($pdo);
$schema = $payload['schema'];
$table = $payload['table'];
$row = $payload['row'];
$metaArr = $meta->getTableMeta($schema, $table);
$schema = $payload['schema'];
$table = $payload['table'];
$row = $payload['row'];
$metaArr = $meta->getTableMeta($schema, $table);
$result = $ds->updateRow($schema, $table, $row, $metaArr['columns'], $metaArr['primaryKey']);
$response->getBody()->write(json_encode($result));
return $response->withHeader('Content-Type', 'application/json');
$result = $ds->updateRow($schema, $table, $row, $metaArr['columns'], $metaArr['primaryKey']);
$response->getBody()->write(json_encode($result));
return $response->withHeader('Content-Type', 'application/json');
} catch (\Exception $e) {
$error = ['error' => true, 'message' => $e->getMessage()];
$response->getBody()->write(json_encode($error));
return $response->withHeader('Content-Type', 'application/json')->withStatus(400);
}
});
$app->post('/api/table/delete', function (Request $request, Response $response) use ($container) {
$payload = json_decode((string)$request->getBody(), true);
$pdo = $container->get('db');
$meta = new \App\MetaService($pdo);
$ds = new \App\DataService($pdo);
try {
$payload = json_decode((string)$request->getBody(), true);
$pdo = $container->get('db');
$meta = new \App\MetaService($pdo);
$ds = new \App\DataService($pdo);
$schema = $payload['schema'];
$table = $payload['table'];
$row = $payload['row'];
$metaArr = $meta->getTableMeta($schema, $table);
$schema = $payload['schema'];
$table = $payload['table'];
$row = $payload['row'];
$metaArr = $meta->getTableMeta($schema, $table);
$result = $ds->deleteRow($schema, $table, $row, $metaArr['primaryKey']);
$response->getBody()->write(json_encode($result));
return $response->withHeader('Content-Type', 'application/json');
$result = $ds->deleteRow($schema, $table, $row, $metaArr['primaryKey']);
$response->getBody()->write(json_encode($result));
return $response->withHeader('Content-Type', 'application/json');
} catch (\Exception $e) {
$error = ['error' => true, 'message' => $e->getMessage()];
$response->getBody()->write(json_encode($error));
return $response->withHeader('Content-Type', 'application/json')->withStatus(400);
}
});
// API: импорт CSV (массовая вставка)
@@ -315,19 +333,25 @@ $app->get('/api/fk-values', function (Request $request, Response $response) use
// API: массовое удаление строк (batch delete)
$app->post('/api/table/delete-batch', function (Request $request, Response $response) use ($container) {
$payload = json_decode((string)$request->getBody(), true);
$pdo = $container->get('db');
$meta = new \App\MetaService($pdo);
$ds = new \App\DataService($pdo);
try {
$payload = json_decode((string)$request->getBody(), true);
$pdo = $container->get('db');
$meta = new \App\MetaService($pdo);
$ds = new \App\DataService($pdo);
$schema = $payload['schema'];
$table = $payload['table'];
$rows = $payload['rows'] ?? []; // Массив строк для удаления
$metaArr = $meta->getTableMeta($schema, $table);
$schema = $payload['schema'];
$table = $payload['table'];
$rows = $payload['rows'] ?? []; // Массив строк для удаления
$metaArr = $meta->getTableMeta($schema, $table);
$result = $ds->deleteMultipleRows($schema, $table, $rows, $metaArr['primaryKey']);
$response->getBody()->write(json_encode($result));
return $response->withHeader('Content-Type', 'application/json');
$result = $ds->deleteMultipleRows($schema, $table, $rows, $metaArr['primaryKey']);
$response->getBody()->write(json_encode($result));
return $response->withHeader('Content-Type', 'application/json');
} catch (\Exception $e) {
$error = ['error' => true, 'message' => $e->getMessage()];
$response->getBody()->write(json_encode($error));
return $response->withHeader('Content-Type', 'application/json')->withStatus(400);
}
});