[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"question-reactive-kak-obrabatyvat-oshibki-v-reaktivnykh-potokakh":3},{"id":4,"slug":5,"topicId":6,"topicSlug":7,"topicName":8,"topicEmoji":9,"question":10,"answer":11,"codeLang":12,"codeSrc":12,"important":12,"commonMistakes":12,"modernUsage":12,"difficulty":13,"tags":14,"related":15,"progress":16,"seo":17},997,"kak-obrabatyvat-oshibki-v-reaktivnykh-potokakh",31,"reactive","Reactive","⚡","Как обрабатывать ошибки в реактивных потоках?","В реактивном программировании ошибка — терминальный сигнал, после которого поток прекращает работу. Project Reactor предоставляет набор операторов для перехвата, замены и восстановления после ошибок.\n\n### Основные операторы обработки ошибок\n\n| Оператор | Назначение | Пример |\n|----------|------------|--------|\n| `onErrorReturn` | Заменить ошибку значением по умолчанию | `flux.onErrorReturn(-1)` |\n| `onErrorResume` | Заменить ошибку альтернативным потоком | `mono.onErrorResume(e -> fallback())` |\n| `onErrorMap` | Преобразовать ошибку в другой тип | `mono.onErrorMap(e -> new ApiException(e))` |\n| `doOnError` | Побочный эффект (логирование) без перехвата | `mono.doOnError(e -> log.error(...))` |\n| `retry` \u002F `retryWhen` | Повторная попытка подписки | `mono.retry(3)` |\n| `onErrorComplete` | Преобразовать ошибку в сигнал завершения | `flux.onErrorComplete()` |\n\n```java\n\u002F\u002F onErrorReturn — значение по умолчанию\nFlux.just(1, 2, 0)\n    .map(i -> 10 \u002F i)\n    .onErrorReturn(-1)\n    .subscribe(System.out::println);\n\u002F\u002F Вывод: 10, 5, -1\n```\n\n```java\n\u002F\u002F onErrorResume — разная обработка для разных типов ошибок\nMono\u003CUser> user = userService.findById(id)\n    .onErrorResume(NotFoundException.class, e -> Mono.empty())\n    .onErrorResume(ServiceException.class, e -> fallbackService.findById(id));\n```\n\n```java\n\u002F\u002F onErrorMap — преобразование типа ошибки\nMono\u003CUser> user = userRepository.findById(id)\n    .onErrorMap(DataAccessException.class,\n                e -> new ServiceException(\"Ошибка БД\", e));\n```\n\n\u003Cdetails>\u003Csummary>Пример: retryWhen с backoff\u003C\u002Fsummary>\n\n```java\nMono\u003CResponse> response = webClient.get()\n    .uri(\"\u002Fapi\u002Fdata\")\n    .retrieve()\n    .bodyToMono(Response.class)\n    .retryWhen(Retry.backoff(3, Duration.ofSeconds(1))\n        .maxBackoff(Duration.ofSeconds(10))\n        .filter(e -> e instanceof WebClientResponseException.ServiceUnavailable)\n        .onRetryExhaustedThrow((spec, signal) ->\n            new ServiceException(\"Сервис недоступен после 3 попыток\")));\n```\n\n\u003C\u002Fdetails>\n\n\u003Cdetails>\u003Csummary>Пример: комбинированная обработка ошибок\u003C\u002Fsummary>\n\n```java\nMono\u003COrderDto> result = orderService.createOrder(request)\n    .doOnError(e -> log.error(\"Ошибка создания заказа\", e))\n    .onErrorMap(DataAccessException.class,\n                e -> new ApiException(500, \"Ошибка базы данных\"))\n    .onErrorMap(ValidationException.class,\n                e -> new ApiException(400, e.getMessage()))\n    .retryWhen(Retry.backoff(2, Duration.ofMillis(500))\n        .filter(e -> e instanceof TransientDataAccessException));\n```\n\n\u003C\u002Fdetails>\n\n### Частые ошибки\n\n- `onErrorReturn` в середине цепочки — поток завершится после возврата значения, последующие элементы Flux не будут эмитированы\n- Бесконечный `retry` без фильтра — бесконечный цикл при постоянной ошибке\n- Retry для неидемпотентных операций — повтор POST-запроса может создать дубликаты\n- Игнорирование ошибок без `doOnError` — если ошибка «проглатывается», важно хотя бы залогировать\n\n### Как используется в 2026\n\n- `retryWhen` с `Retry.backoff` — стандартный паттерн для устойчивости микросервисов\n- Интеграция с Resilience4j для circuit breaker + retry\n- Spring WebFlux: `@ExceptionHandler` и `WebExceptionHandler` для глобальной обработки\n- Structured error handling через `onErrorResume` с разными типами исключений — best practice\n\n> **На собеседовании:** покажите знание нескольких операторов и объясните разницу: onErrorReturn заменяет значением, onErrorResume — потоком, onErrorMap — типом ошибки, doOnError — побочный эффект. Частая ошибка — не знать, что порядок операторов важен: ошибка перехватывается ближайшим оператором ниже по цепочке.","","middle",[7],[],null,{"title":18,"description":19,"ogTitle":18,"ogDescription":20,"keywords":21,"schemaAnswer":22,"featuredSnippetReady":23},"Как обрабатывать ошибки в реактивных потоках? — Gymterview","В реактивном программировании ошибка — терминальный сигнал, после которого поток прекращает работу. Project Reactor предоставляет набор операторов для перехвата","В реактивном программировании ошибка — терминальный сигнал, после которого поток прекращает работу. Project Reactor пред",[7,13],"В реактивном программировании ошибка — терминальный сигнал, после которого поток прекращает работу. Project Reactor предоставляет набор операторов для перехвата, замены и восстановления после ошибок.",true]