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

时间:2017-06-06 10:26:31

标签: spring kotlin reactive

在数据类中,我定义'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()
        )
  }
}

1 个答案:

答案 0 :(得分:2)

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) }
      )
}