Нужно чуть больше контекста (какой язык/фреймворк, где именно — контроллер, сервис, транзакция?), но в общих чертах — вы просто поднимаете (throw / raise) подходящее исключение в месте проверки при обновлении задачи и даёте обработчику (или middleware) сформировать нужный HTTP-ответ/откат транзакции. Привожу краткие примеры для популярных стеков и рекомендации:
Общие принципы
- Решите, какое исключение соответствует ситуации: NotFound (404), BadRequest (400), Conflict (409) для конфликтов версий/конкурентности, или просто Internal (500) для непредвиденной ошибки.
- В сервисном слое бросайте бизнес-исключения; контроллер/глобальный обработчик превращает их в HTTP-ответ.
- Если нужна отмена изменений в БД — выполняйте в транзакции и бросайте исключение (Runtime/unchecked или настроенным rollbackFor) чтобы транзакция откатилась.
Примеры
Java + Spring (контроллер → сервис)
- В сервисе:
if (task == null) {
throw new EntityNotFoundException("Task not found: " + id);
}
if (!isValid(request)) {
throw new IllegalArgumentException("Invalid data");
}
- В контроллере можно вернуть ResponseEntity или использовать @ControllerAdvice:
@ExceptionHandler(EntityNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public ErrorDto handleNotFound(...) { ... }
Чтобы транзакция откатывалась, используйте @Transactional (по умолчанию откатывает RuntimeException):
@Transactional
public void updateTask(...) {
if (someCondition) throw new RuntimeException("fail");
// изменения...
}
C# ASP.NET Core
- В контроллере/сервисе:
if (task == null) throw new KeyNotFoundException($"Task {id} not found");
if (!ModelState.IsValid) throw new ArgumentException("Invalid input");
- Перехват в middleware/exception filter и преобразование в статус-код:
app.UseExceptionHandler(...);
Python + Django
- Во view или сервисе:
from django.core.exceptions import ObjectDoesNotExist, ValidationError
try:
task = Task.objects.get(pk=id)
except Task.DoesNotExist:
raise Http404("Task not found")
if not valid:
raise ValidationError("Invalid data")
- Для отката используйте @transaction.atomic и просто raise исключение — транзакция откатится.
Node.js + Express
- В async-обработчике:
const task = await Task.findById(id);
if (!task) {
const err = new Error('Not found');
err.status = 404;
throw err; // или next(err)
}
- И используйте централизованный error handler (app.use((err, req, res, next) => { ... })).
Оптимистичная блокировка (конкурентность)
- Добавьте версию/ETag: если версия отличается — выбросьте Conflict (409).
- Пример: if (incomingVersion !== task.version) throw new ConflictException("Stale object");
Если подскажете язык/фреймворк и фрагмент кода — покажу конкретный пример и как правильно преобразовать исключение в ответ API и/или откат транзакции.