You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Storage trait实现类的NonFatal异常自动包装为StorageWriteException?

统一处理Storage实现类的异常包装方案

完全不需要在每个实现类里手动包装异常!我们可以利用Scala trait的特性,把异常捕获逻辑统一封装在trait层面,让子类只需要专注于实现实际的写入逻辑就行。

具体实现步骤

  1. 改造Storage trait
    把原来的抽象write方法改成具体方法,同时新增一个受保护的抽象方法(比如doWrite)让子类实现实际写入逻辑。在trait的write方法里统一处理异常捕获和包装:
import scala.util.control.NonFatal

trait Storage {
  // 对外暴露的公共方法,由trait统一实现异常包装
  def write(data: Array[Byte]): Unit = {
    try {
      doWrite(data)
    } catch {
      case NonFatal(e) => 
        throw new StorageWriteException(e)
    }
  }

  // 子类必须实现的实际写入逻辑,protected限制只能子类访问
  protected def doWrite(data: Array[Byte]): Unit
}
  1. 保留你的异常类
class StorageWriteException(t: Throwable) extends RuntimeException(t)
  1. 子类实现示例
    子类只需要专注于实现doWrite方法,完全不用管异常处理——所有NonFatal异常都会被父trait的write方法自动捕获并包装:
import java.io.FileOutputStream

class FileStorage(path: String) extends Storage {
  override protected def doWrite(data: Array[Byte]): Unit = {
    val fos = new FileOutputStream(path)
    try {
      fos.write(data)
    } finally {
      fos.close()
    }
    // 这里如果抛出IO异常等NonFatal异常,会被自动包装成StorageWriteException
  }
}

关键说明

  • 避免子类重写write方法:如果子类重写了write,会覆盖trait里的异常处理逻辑,所以要提醒实现者只需要实现doWrite即可。如果确实需要扩展write,记得调用super.write(data)来复用统一的异常包装逻辑。
  • NonFatal的范围:Scala的NonFatal排除了VM错误、线程死亡等致命异常,这些异常通常不需要我们包装,交给JVM处理更合适,所以这个范围刚好符合业务需求。

内容的提问来源于stack exchange,提问作者Some Name

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:51:24