如何在Kotlin+Arrow中安全关闭InputStream并返回Either错误?
解决方案
方案1:结合Kotlin标准库use与runCatching
Kotlin的use函数本身会保证InputStream在代码块执行完成后被关闭——无论代码块是正常返回还是抛出异常。你只需要在use的代码块内,用runCatching捕获所有可能的异常,并转换为Arrow的Either类型即可。
修改后的代码:
import arrow.core.Either import arrow.core.left import arrow.core.right import org.apache.commons.io.IOUtils import java.io.InputStream import java.nio.charset.Charset fun pipeline(inputStream: InputStream): Either<Throwable, String> { return inputStream.use { stream -> runCatching { // 读取流内容 val input = IOUtils.toString(stream, Charset.defaultCharset()) // 解析JSON,失败则抛出异常交给runCatching统一处理 val event = fromJson<S3EventNotification.S3Event>(input).fold( { throw it }, { it } ) // 获取业务数据,失败同样抛出异常 val key = event.records.first().s3.s3object.key getZoomLocationData(key).fold( { throw it }, { it.toString() } ) }.fold( { it.left() }, // 所有异常转为Either.Left { it.right() } // 正常结果转为Either.Right ) } }
核心逻辑
use全权负责InputStream的安全关闭,无需手动编写finally块runCatching捕获代码块内所有异常(包括主动抛出的解析/业务错误)- 通过
fold将Either的Left值抛出,统一由runCatching捕获后转为最终的Either.Left
方案2:使用Arrow官方资源管理API(贴合函数式风格)
Arrow提供了Resource工具类,专门用于函数式场景下的资源生命周期管理,和Either、effect等API无缝集成,代码更简洁:
import arrow.core.Either import arrow.core.continuations.effect import arrow.resources.Resource import org.apache.commons.io.IOUtils import java.io.InputStream import java.nio.charset.Charset fun pipeline(inputStream: InputStream): Either<Throwable, String> = effect { // 将InputStream包装为Arrow资源,自动处理关闭逻辑 val stream = Resource.fromCloseable { inputStream }.bind() val input = IOUtils.toString(stream, Charset.defaultCharset()) // 用bind直接提取Either.Right的值,Left会自动转为异常终止流程 val event = fromJson<S3EventNotification.S3Event>(input).bind() val key = event.records.first().s3.s3object.key val locationData = getZoomLocationData(key).bind() locationData.toString() }.toEither()
核心逻辑
Resource.fromCloseable将InputStream转为Arrow资源,确保流程结束后自动关闭effect块自动捕获所有异常,bind()简化了Either的处理:若为Left则终止流程并将异常传入最终的Either;若为Right则提取值继续执行- 最终调用
toEither()将Effect类型转为Either<Throwable, String>
内容的提问来源于stack exchange,提问作者pbuchheit
相关产品推荐
相关产品推荐

