gpt4 book ai didi

elixir - 处理 Absinthe 中的异常

转载 作者:行者123 更新时间:2023-12-04 17:33:50 26 4
gpt4 key购买 nike

问题

中有很多可用于处理错误元组的指南。但在异常(exception)情况下接近零。

这很重要,因为总会有无法预料的问题,这些问题可能会引发异常并返回不符合 的响应。响应/错误规范。当 GraphQL 客户端喜欢 时,这尤其成问题。自动批处理请求,一个查询中的异常将使整个 BEAM 网络进程崩溃,导致所有查询失败。


现有方法

我的第一个想法是使用中间件将解析器包装在 try/rescue block 中,我遇到的仅有的两个链接也提出了类似的方法:

  • Elixir 论坛: How to use Absinthe.MiddleWare to catch exception?

    • Ben Wilson,Absinthe 的创建者之一,建议将 Resolution 中间件替换为在 try block 中执行解析器的自定义中间件

    • 这不会处理其他中间件中的异常(但也许它应该是这样的)

  • 博客文章: Handling Elixir Exceptions in Absinthe using Middleware

    • 尝试做同样的事情,但不遵循 Absinthe.Middleware 行为规范
    • 而是将所有现有的中间件包装在匿名函数中
    • 因此,我们在检查启用的中间件及其配置时也会失去洞察力

我的解决方案

我的方法有点受到博客文章的启发,但我尝试遵循该行为并使用中间件元组规范而不是匿名函数:

中间件定义:

defmodule MyApp.ExceptionMiddleware do
@behaviour Absinthe.Middleware
@default_error {:error, :internal_server_error}
@default_config []

@spec wrap(Absinthe.Middleware.spec()) :: Absinthe.Middleware.spec()
def wrap(middleware_spec) do
{__MODULE__, [handle: middleware_spec]}
end

@impl true
def call(resolution, handle: middleware_spec) do
execute(middleware_spec, resolution)
rescue
error ->
Sentry.capture_exception(error, __STACKTRACE__)
Absinthe.Resolution.put_result(resolution, @default_error)
end

# Handle all the ways middleware can be defined

defp execute({{module, function}, config}, resolution) do
apply(module, function, [resolution, config])
end

defp execute({module, config}, resolution) do
apply(module, :call, [resolution, config])
end

defp execute(module, resolution) when is_atom(module) do
apply(module, :call, [resolution, @default_config])
end

defp execute(fun, resolution) when is_function(fun, 2) do
fun.(resolution, @default_config)
end
end

在架构中应用它:

wrap/1 方法在所有查询/变异中间件上调用

def middleware(middleware, _field, %{identifier: type}) when type in [:query, :mutation] do
Enum.map(middleware, &ExceptionMiddleware.wrap/1)
end

结果:

将它们转换为:

[
{ExceptionMiddleware, handle: {AuthMiddleware, [access: :admin]}},
{ExceptionMiddleware, handle: {{Resolution, :call}, &some_resolver/3}},
{ExceptionMiddleware, handle: {Subscription, []}},
{ExceptionMiddleware, handle: &anon_middleware/2},
]

问题

我仍然对我的方法没有完全的信心,因为这感觉有点老套并且是对 absinthe 中间件的误用。因此,我有兴趣获得以下几个问题的答案:

  • 还有哪些其他可能的方法?毕竟使用 Absinthe 中间件是正确的选择吗?
  • 如果是这样,包装所有中间件或只替换 Absinthe.Resolution 中间件是否有意义?
  • 这样做的规范方式是什么?

最佳答案

此处为 Decisiv我们正在使用一个名为 Blunder 的内部工具用于处理异常和错误。这可能对您有用。

https://github.com/Decisiv/blunder-absinthe

关于elixir - 处理 Absinthe 中的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57491077/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com