如何在使用 onErrorMap() 处理异常时访问 Mono<T>?

How to Access Mono<T> While Handling Exception with onErrorMap()?

在数据 class 中,我定义了 'name' 在整个 mongo 集合中必须是唯一的:

@Document
data class Inn(@Indexed(unique = true) val name: String,
               val description: String) {
  @Id
  var id: String = UUID.randomUUID().toString()

  var intro: String = ""
}

所以在服务中,如果有人再次传递相同的名称,我必须捕获意外的异常。

@Service
class InnService(val repository: InnRepository) {
  fun create(inn: Mono<Inn>): Mono<Inn> =
      repository
          .create(inn)
          .onErrorMap(
              DuplicateKeyException::class.java,
              { err -> InnAlreadyExistedException("The inn already existed", err) }
          )
}

这没问题,但是如果我想向 "The inn named '$it.name' already existed" 之类的异常消息添加更多信息,我应该如何使用丰富的消息转换异常。

显然,一开始就将 Mono<Inn> 赋值给局部变量不是一个好主意...

处理程序中的类似情况,我想为客户提供更多源自自定义异常的信息,但找不到合适的方法。

@Component
class InnHandler(val innService: InnService) {
  fun create(req: ServerRequest): Mono<ServerResponse> {
    return innService
        .create(req.bodyToMono<Inn>())
        .flatMap {
          created(URI.create("/api/inns/${it.id}"))
              .contentType(MediaType.APPLICATION_JSON_UTF8).body(it.toMono())
        }
        .onErrorReturn(
            InnAlreadyExistedException::class.java,
            badRequest().body(mapOf("code" to "SF400", "message" to t.message).toMono()).block()
        )
  }
}

reactor 中,您不会在 onErrorMap 中获得想要传递给您的值作为参数,您只会得到 Throwable。但是,在 Kotlin 中,您可以超出错误处理程序的范围,直接引用 inn。你不需要做太多改变:

fun create(inn: Mono<Inn>): Mono<Inn> =
    repository
      .create(inn)
      .onErrorMap(
          DuplicateKeyException::class.java,
          { InnAlreadyExistedException("The inn ${inn.name} already existed", it) }
      )
}