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

Akka Http客户端报错:在TypedActor实现方法外调用TypedActor.context

问题描述

我参考示例构建Akka Http客户端时遇到错误,以下是相关代码及报错信息:

客户端实现代码

trait HttpServer {
   def sendAndReceive: HttpRequest => Future[HttpResponse]
}

trait ApiHandler extends HttpServer {
  implicit def as: ActorSystem
  override def sendAndReceive: HttpRequest => Future[HttpResponse] =
     Http().singleRequest(_)
 }

trait Api {
    this: ApiHandler =>

    implicit def as: ActorSystem
    implicit def mat: Materializer
    implicit def ec: ExecutionContext

    def request(httpRequest: HttpRequest): Future[HttpResponse] = {
      sendAndReceive(httpRequest).flatMap { response =>
         response.status match {
           case StatusCodes.OK => Future.successful(response)
           case _ => throw new RuntimeException ("error")
        }
      }
    }
  }

  class ApiImpl() (implicit val as: ActorSystem, val mat: Materializer, val ec: ExecutionContext) extends Api with ApiHandler {
       def request: Future[HttpResponse] = {
       val httpRequest = ???
       request(httpRequest)
       }
   }

调用代码

implicit val actorSystem = ActorSystem("system")
  implicit val executionContext = actorSystem.dispatcher
  implicit val materializer = ActorMaterializer()

  val api = new ApiImpl()
  api.request

错误信息

在Api trait中sendAndReceive(httpRequest).flatMap { response =>这一行,触发如下错误:

Calling TypedActor.context outside of a TypedActor implementation method!

问题分析与修复

错误原因

  1. Http().singleRequest隐式依赖不全:Http().singleRequest需要隐式的ActorSystem、Materializer和ExecutionContext三者才能正常工作,但你的ApiHandler trait仅声明了ActorSystem,缺失另外两个关键隐式参数,导致Akka内部尝试从错误的上下文(如TypedActor的context)获取依赖,从而抛出异常。
  2. ApiImpl存在递归调用问题:ApiImpl中的request方法未构造合法的HttpRequest实例,反而直接调用request(httpRequest),会触发无限递归,即使解决了第一个错误,后续也会出现栈溢出异常。

修复方案

  1. 给ApiHandler补充完整的隐式参数:
trait ApiHandler extends HttpServer {
  implicit def as: ActorSystem
  implicit def mat: Materializer
  implicit def ec: ExecutionContext

  override def sendAndReceive: HttpRequest => Future[HttpResponse] =
     Http().singleRequest(_)
 }
  1. 修正ApiImpl的递归问题,实现具体请求逻辑:
class ApiImpl() (implicit val as: ActorSystem, val mat: Materializer, val ec: ExecutionContext) extends Api with ApiHandler {
     // 重命名方法避免与trait中的request冲突,同时构造合法请求
     def fetchTargetResource(): Future[HttpResponse] = {
       val httpRequest = HttpRequest(
         HttpMethods.GET,
         uri = "http://your-target-api.com/path" // 替换为实际请求地址
       )
       request(httpRequest)
     }
 }
  1. 调用修正后的方法:
implicit val actorSystem = ActorSystem("system")
implicit val executionContext = actorSystem.dispatcher
implicit val materializer = ActorMaterializer()

val api = new ApiImpl()
api.fetchTargetResource()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 18:32:28