API обещает: HTTP 200 означает сохранённый отчёт. Ответ 200 есть, отчёта нет.
API обещает: HTTP 200 означает сохранённый отчёт. Ответ 200 есть, отчёта нет. Учебный фрагмент Java SE 17, не самостоятельная программа. `createReportAsync()` возвращает `CompletableFuture<Report>`, `Report.empty()` — заглушку без сохранения. Типы и логгер условные; HTTP-адаптер отправляет `HttpReply` после нормального завершения возвращённого stage: java CompletableFuture<Report> source = createReportAsync(); CompletableFuture<Report> recovered = source.exceptionally(error -> { log.warn("REPORT_FAILED", error); return Report.empty(); // fallback не сохранён как отчёт }); return recovered.thenApply(report -> new HttpReply(200, report)); Вымышленный след, не результат запуска; лог показан схематично: contract: HTTP 200 = отчёт создан и сохранён log: REPORT_FAILED; причина — StorageException source: completed exceptionally; причина — StorageException recovered: completed normally, value=Report.empty() response: HTTP 200; saved report: absent Ошибка осталась в `source`, но обработчик `exceptionally` нормально вернул заглушку. Поэтому `recovered` завершился нормально, а `thenApply` создал ответ 200. Развилка для ревью: проверьте исходную ошибку, значение после обработчика и обещание API. Нормальный статус stage не делает заглушку созданным отчётом. Если контракт обещает только приём задания, вывод нужно оценивать отдельно. Типичная ошибка — принять fallback за бизнес-успех. Добавление `join()` само по себе этого не исправляет: нужно определить, удовлетворяет ли замена контракту и как сообщить клиенту об отказе. Сохраните пример для ревью асинхронного кода; обработку ошибок Java полезно разбирать на рабочих сценариях. #Java #CompletableFuture #РазработкаПО #УЦФОРС