source

Reactor에서 예외를 설정하는 올바른 방법

manysource 2022. 11. 5. 17:38

Reactor에서 예외를 설정하는 올바른 방법

저는 Reactor와 리액티브 프로그래밍을 처음 해보는 사람입니다.

현재 다음과 같은 코드를 만들고 있습니다.

Mono.just(userId)
    .map(repo::findById)
    .map(user-> {
        if(user == null){
            throw new UserNotFoundException();
        }
        return user;
    })
    // ... other mappings

이 예는 아마 우습고 이 케이스를 구현하는 더 나은 방법이 있을 것입니다만, 요점은 다음과 같습니다.

를 사용하는 것이 잘못되었습니까?throw newmap을 「」로 인가.return Mono.error(new UserNotFoundException())

이 두 가지 방법에 실제 차이가 있나요?

예외 발생을 방지하는 편리한 방법으로는 다음과 같은 몇 가지 방법이 있습니다.

를 조작하려면 , 「」를 사용합니다.Flux/Mono.handle

빈이 있는 할 수 중 는 연산자 「」입니다.handle.

다음 코드는 문제를 해결하기 위해 이 코드를 사용하는 방법을 보여 줍니다.

Mono.just(userId)
    .map(repo::findById)
    .handle((user, sink) -> {
        if(!isValid(user)){
            sink.error(new InvalidUserException());
        } else if (isSendable(user))
            sink.next(user);
        }
        else {
            //just ignore element
        }
    })

.handle해야 .BiConsumer<T, SynchronousSink<>요소를 처리하기 위해.BiConsumer(바이컨슈머) 번째 이며, 두 번째 는 업스트림의 요소입니다.SynchronousSink다운스트림에 동기적으로 요소를 공급하는 데 도움이 됩니다.이러한 기술은 요소 처리의 다른 결과를 제공할 수 있는 능력을 확장합니다.들어 요소가 않은 경우 할 수 .SycnchronousSync되고 '''가 생성됩니다.onError하다'필터링'을 할 수 있어요.handle손잡이 BiConsumer실행되며 요소가 제공되지 않습니다.Reactor는 이를 필터링의 종류로 간주하여 추가 요소를 요구합니다., '만일', '만일', '만일', '만일', '만일'이라고 부르면 됩니다.SynchronousSink#next ' 정도 맵핑'이 됩니다.handlemap오퍼레이터입니다.또한 성능 저하 없이 해당 오퍼레이터를 안전하게 사용할 수 있으며 요소의 검증이나 다운스트림으로의 에러 송신 등 복잡한 요소 검증을 제공할 수 있습니다.

를 사용해서 던집니다.#concatMap+Mono.error

중에 중 는 맵핑에서 예외를 발생시킬 수 옵션 중 하나는 맵핑에서 예외를 발생시키는 입니다.mapconcatMap그 본질은concatMap 일을 하다flatMap이 있다면, 그 차이점이 요. 유일한 차이점은concatMap는 한번에 1개의 서브스트림만 허용합니다.이러한 동작은 내부 구현을 크게 간소화하고 성능에 영향을 주지 않습니다.따라서 다음 코드를 사용하여 보다 기능적인 방법으로 예외를 발생시킬 수 있습니다.

Mono.just(userId)
    .map(repo::findById)
    .concatMap(user-> {
        if(!isValid(user)){
            return Mono.error(new InvalidUserException());
        }
        return Mono.just(user);
    })

사용자의 .Mono.error로 플럭스에도 할 수 Flux.error:

Flux.just(userId1, userId2, userId3)
    .map(repo::findById)
    .concatMap(user-> {
        if(!isValid(user)){
            return Flux.error(new InvalidUserException());
        }
        return Mono.just(user);
    })

경우 모두 하나의 요소만 있는 콜드 스트림을 반환합니다.Reactor에서는 반환되는 스트림이 콜드 스칼라 스트림인 경우 성능을 향상시키는 몇 가지 최적화가 있습니다.따라서 Flux/Mono 사용을 권장합니다.concatMap+.just,empty,error 복잡한 매핑이 때, 그, 보, 보, 과로 끝날 수 .return null ★★★★★★★★★★★★★★★★★」throw new ....

주목! 들어오는 요소를 절대 확인하지 마십시오. Reactive Streams 사양(규칙 2.13 참조)에 위반되기 때문에 Reactor Project는 값을 송신하지 않습니다.따라서 다음과 같은 경우repo.findById.Reactor(리액터) 늘 포인터외입니니다다

왜 wait, ??concatMap보다 flatMap

,본 in in in in inflatMap는 동시에 실행되는 여러 서브스트림의 요소를 결합하도록 설계되어 있습니다., 그에 비동기 이 있어야 여러 상의 를 처리할 도 있고 콜이 도 있습니다.후, 에 큰 을 미치기 때문에, 이러한 기대는 이행에 큰 영향을 미칩니다.flatMap의 스트림으로부터의 할 수 필요가 (이러한 경우).Thread ( 데이터의 사용 예), 다른의 추가 예), 요소(의 추가 메모리 할당 예), enqueue 요소.Queue각 서브스트림에 대해 s) 및 Reactive Streams 사양 규칙을 위반하지 않아야 합니다(실장이 매우 복잡함을 의미합니다). map(를 사용하여 조작Flux/Mono.error하지 않음)에 따라 훨씬 더 (실행 동기성) 연산자를 할 수 .concatMap이는 한 번에 단일 스트림의 비동기 처리를 위해 설계되었으며 스칼라 콜드 스트림을 처리하기 위해 몇 가지 최적화 기능을 갖추고 있습니다.

사용하여 를 발생시킵니다.switchIfEmpty

결과가 있을 때 또 은 '비우다'입니다.switchIfEmpty 에서는 어떻게하면 좋은지 알 수 .

Mono.just(userId)
    .flatMap(repo::findById)
    .switchIfEmpty(Mono.error(new UserNotFoundExeception()))

repo::findById 한다MonoUser반환 유형으로 지정됩니다.'의 User인스턴스를 찾을 수 없습니다. 이치노Reactor는 Reactor를 합니다.Mono )로 지정됩니다.switchIfEmpty파라미터를 지정합니다.

있는 (의 예:map,filter★★★★★★★★★★★★★★★★★★★★★★★」

읽기 어려운 코드 또는 잘못된 관행( 의견)으로 간주될 수 있지만, 예외는 그대로 둘 수 있습니다(예:.map(v -> throw ...)프로젝트 리액터 포함.어떤 면에서는 이렇게 하면 Reactive Streams 사양을 위반할 수 있습니다(이 문맥에서는 후드 아래의 연산자는SubscriberSubscriber - 은 s에 수 .onNext(스펙 규칙 2.13)을 위반하는 메서드).단, Reactor는 투척된 예외를 검출하여 그 예외를 전파합니다.onError다운스트림에 신호를 보내는 것은 금지되지 않습니다.

테이크 아웃

  1. .handle 요소
  2. concatMap+Mono.error매핑 중에 예외를 발생시킬 필요가 있지만 이러한 기술은 비동기 요소 처리의 경우에 가장 적합합니다.
  3. flatMap+Mono.error 먹었을 때flatMap
  4. Null되어 있기 에, 「복귀 타입」이 아닌, 「 타입」이 금지되어 있습니다.nullmap의 일이 onErrorNullPointerException
  5. switchIfEmpty특정 함수를 호출한 결과가 스트림으로 종료된 경우 오류 신호를 전송해야 하는 모든 경우

언급URL : https://stackoverflow.com/questions/53595420/correct-way-of-throwing-exceptions-with-reactor