当前位置: 首页 > 知识库问答 >
问题:

scala Futures:是否有可能发现是否安装了“onFailure”回调(因此我们可以实现默认错误处理)?

拓拔富
2023-03-14

我的问题在某种程度上与Scala futures的默认错误处理程序相关。

奇怪的是,我想安装一个默认的错误处理程序,只有在Future上没有安装onFailure(或on完成)回调时才会启动。我认为这将非常有用,因为我编写的代码中我的Futures会无声地失败,让我对发生了什么感到困惑。后备错误处理程序将使我能够轻松地识别从未定义过适当的onFailure回调的错误Futures。

下面是一个代码示例,它说明了这在哪些方面可能有用。

  import scala.concurrent.ExecutionContext.Implicits.global
  import scala.concurrent._
  import scala.language.implicitConversions
  import scala.language.postfixOps

  def futureWithLogging[T](fut: Future[T]) =
    fut.transform(identity, { t: Throwable =>
      Console.err.println(s"failed with $t")
      t
    })


  {
    val f = futureWithLogging ( Future {
      Thread.sleep(1000)
      throw new scala.RuntimeException("")
    } )

    f.onFailure{ case err:Throwable => {println("custom error message"); err.printStackTrace()} }

    println(s"future value is: ${f.value}")
    Thread.sleep(1000)
    println(s"future value is now: ${f.value}")
    Thread.sleep(1000)
  }

请注意,我有一个futureWithLogging函数,它会在您传递给该函数的任何future上安装一些默认的错误处理行为。现在,如果我忘记在未来安装一个onFailure,这是非常方便的。但是在上面的代码中,你可以看到我在Future 'f '上安装了一个onFailure处理程序。结果是我的日志中有噪音。我看到两条错误消息:

  failed with <exception>  

   custom error message...

在这种情况下,我只想看到第二个

非常感谢您提供的任何指导!

共有1个答案

秦钟展
2023-03-14

最接近我想要的,是让任何特定的故障处理程序将异常包装在一个特殊的“HandledException”包装器中,默认的失败处理程序可以特别处理(忽略,或打印合适的消息,或者其他什么)。例如:

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent._
import scala.language.implicitConversions
import scala.language.postfixOps

case class HandledException(inner: Throwable) extends RuntimeException(inner)

def futureWithLogging[T](fut: Future[T]) =
  fut.transform(identity, { t: Throwable =>
    Console.err.println(s"failed with $t")
    HandledException(t)
  })


{
  val f = futureWithLogging ( Future {
    Thread.sleep(1000)
    throw new scala.RuntimeException("")
  } )

  f.onFailure {
    case HandledException(inner) => println("Already handled: "+inner)
    case err:Throwable => {println("custom error message"); err.printStackTrace()}
  }

  println(s"future value is: ${f.value}")
  Thread.sleep(1000)
  println(s"future value is now: ${f.value}")
  Thread.sleep(1000)
}

从这里,您可以向“HandledException”类添加一个问题ID,它可以在首次捕获初始异常的地方打印出来,然后传递给前端(并且可能在途中通过诸如默认处理程序之类的东西打印出短手)并向用户显示一条消息,例如“对不起,我们遇到了一个错误——您可以向我们的支持人员发送电子邮件,引用问题ID'...'寻求帮助”或任何您喜欢的信息。此ID可以存储在DB中,通过日志文件进行跟踪(如果合适,可能会放入日志框架的诊断上下文中)等。

 类似资料:
  • 所以,我一直在读C++标准,找到了[defns.Undefined](3.27,在我正在读的C++17草案中,请注意,当我在这里引用C++17时,我在其他标准中发现了类似的措辞)--这是未定义行为的定义。我注意到这样的措辞(强调我的): 注意:当本国际标准省略任何行为的明确定义时,或者当程序使用错误的构造或错误的数据时,可能会出现未定义的行为 现在,想想看,这有点道理。这有点像是说,如果标准没有给

  • 访问 xxx_m.jpg 或 xxx_m.jpeg ,如果返回 404 或 403 ,则重定向到 xxx.jpg 或 xxx.jpeg 可以理解为实现“访问压缩图 url ,如果 访问不到,则重定向原图 url” 问了 AI ,回答我是可以实现的,但是运维同学说实现不了,不确定 AI 是不是瞎扯的,有没有大佬解答下。 下面贴下 AI 给的配置:

  • 所以我有这段代码,但在我实际使用它之前,我无法知道函数需要多少参数 有没有可能修改这个函数,让它允许我插入我需要的参数?

  • 我计划开发一个基于web的聊天应用程序,它接收ReSTful请求,将它们转换为XMPP,并将它们发送到XMPP服务器。 在这种基于聊天的应用程序中使用WebSocket看起来很有希望,因为事件(或响应)可以异步传递。但是,如果我使用WebSocket作为从浏览器传输请求的底层协议,这仍然可以被视为ReSTful设计吗?如果是的话,URI、动词(GET、POST…)是怎样的,websocket消息中

  • 使用Fork-Join框架的资源,创建一个同步多线程系统,从三个文本文件中形成一个最大长度的单词集合。不要使用中间集合来读取文本。在本例中,工作由存储在MaxLengthWord类的arr字段中的数组表示。createSubtasks()方法递归地将任务分成更小的工作部分,直到每个工作部分都小于阈值。

  • 我正在研究Java类和继承,我对接口有疑问。 根据Oracle文档,LinkedList类实现了可序列化、可克隆、可重用、集合、定义、列表和队列。 因为Iterable是一个接口,而不是像LinkedList那样的类,所以它必须实现一个默认迭代器,不是吗?如果理解正确,我在哪里可以看到实现?