自定义异常和类型规范

Custom Exceptions and type specs

在 elixir 中你可以像这样定义一个自定义异常:

defmodule AppWeb.CustomError do
  defexception message: "some custom server error", plug_status: 500
end

但这不再是 Elixir.Exception

因此,如果您将它与定义了此类类型规范的第三方库一起使用:

  @spec capture_exception(Exception.t, Keyword.t) :: task
  def capture_exception(exception, opts \ []) do

  ...

  Sentry.capture_exception(AppWeb.CustomError,
                         [stacktrace: System.stacktrace()]

dialyzer 将因 breaks the contract 而崩溃,因为 CustomError 不是异常:

The call 'Elixir.Sentry':capture_exception('Elixir.AppWeb.CustomError',[{'stacktrace',[{atom(),atom(),[any()] | byte(),[{'file',string()} | {'line',pos_integer()}]}]},...]) breaks the contract ('Elixir.Exception':t(),'Elixir.Keyword':t()) -> task()

你能以某种方式在 AppWeb.CustomError 中扩展 Elixir.Exception 模块吗?或者如何遵循最佳实践来解决这个问题?

您传递的是模块名称 (AppWeb.CustomError) 而不是它的实例 (%AppWeb.CustomError{})。该模块的实例将满足 Exception.t 类型。

Sentry.capture_exception(%AppWeb.CustomError{},
                         [stacktrace: System.stacktrace()]