我正在编写一段 Kotlin 代码,该代码使用反应器框架来实现对 Gitlab 提交 API 的调用。提交 API 是分页的。我正在努力检索的函数“在”两个指定的提交哈希之间检索提交。
只要它实际上可以检索任何提交,该函数就可以正常工作,但如果找不到结果则失败。然后它失败了
java.lang.RuntimeException: Reached end of commit log
。
我尝试用 替换该行.switchIfEmpty(Flux.error(RuntimeException("Reached end of commit log.")))
,.switchIfEmpty(Flux.empty())
但这会产生无限循环。
我不太了解多个通量的嵌套,这让我很难调试。我非常感谢有关如何解决此问题的任何提示。
fun getCommits(fromCommit: String, toCommit: String): Iterable<Commit> {
val commits = Flux.concat(Flux.generate<Flux<GitLabCommit>, Int>({ 1 }) { state, sink ->
val page = client.get()
.uri("/projects/{name}/repository/commits?page=$state&per_page=100")
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.bodyToFlux<GitLabCommit>()
.doOnError({
LOGGER.warn("Could not retrieve commits for project '$name': ${it.message}")
sink.next(Flux.just(GitLabCommit("xxxxx", "Could not retrieve all commits for project '$name'")))
sink.complete()
})
.onErrorReturn(GitLabCommit("xxxxx", "Could not retrieve all commits for project '$name'"))
.switchIfEmpty(Flux.error(RuntimeException("Reached end of commit log.")))
sink.next(page)
return@generate state + 1
})
return commits
// The Gitlab API returns commits from newest to oldest
.skipWhile { !it.id.startsWith(toCommit) } //inclusive
.takeWhile { !it.id.startsWith(fromCommit) } //exclusive
.map { Commit(it.title, listOf(it.id), name) }
.toIterable()
}
关于上述代码的其他提示:
这是 GitlabCommit 类:
@JsonIgnoreProperties(ignoreUnknown = true)
private data class GitLabCommit(val id: String, val title: String)
是的client
一个正确初始化的实例org.springframework.web.reactive.function.client.WebClient.Builder
,它有助于令牌处理和 URL 编码。