Faraday: Rety Middleware 不会在解析器之后运行

创建于 2021-04-23  ·  4评论  ·  资料来源: lostisland/faraday

基础信息

  • 法拉第版本:1.4.1
  • 红宝石版本:2.7.2

问题描述

_NB:请让我知道这是否属于faraday_middleware 。 因为它涉及到两个中间件,我不知道把它放在哪里。_

创建连接时,我希望(如文档所述)中间件将按照它声明的顺序运行。 然而,当请求将失败并予加载:json解析中间件接着:retry中间件, env.body处于的范围未解析:retry中间件的:retry_if块:

我需要在JSON -decoded 消息上运行:retry_if块,因为如果请求成功,JSON 文档可能非常大,另一种方法是在retry_if ,这似乎完全没有必要。

重现步骤

<strong i="23">@_client</strong> ||= Faraday.new(url: ROOT_URL) do |f|
      f.options[:timeout] = 10
      f.headers['Content-Type'] = 'application/json'
      f.use :instrumentation, name: INSTRUMENTATION_EVENT_NAME
      f.response :json, content_type: /\bjson$/
      f.request :retry, FARADAY_RETRY_OPTIONS
end

注意:如果我在块内打印f.instance_variable_get :@handlers ,我会按照我声明的顺序看到中间件。

当请求失败时,我在:retry中间件的:retry_if块中评估这些表达式,我得到以下输出:

(byebug) environment.response.to_hash.without(:url)
{:status=>405, :body=>"{\"message\": \"The method is not allowed for the requested URL.\"}\n", :response_headers=>{"date"=>"Fri, 23 Apr 2021 18:17:16 GMT", "content-type"=>"application/json", "content-length"=>"64", "connection"=>"keep-alive", "server"=>"gunicorn", "allow"=>"HEAD, OPTIONS, GET"}}

(byebug) environment.response.body
"{\"message\": \"The method is not allowed for the requested URL.\"}\n"
(byebug) environment.response.body.class
String

基本上,解析中间件只是拒绝首先运行。

JSON 格式正确并且响应的Content-Type标头设置正确,所以我很难过。

我唯一的猜测是它与#response中间件总是在#request中间件之前运行有关,但在这种情况下retry#request中间件有点用词不当因为它隐含地需要在返回响应后进行评估。

最有用的评论

@mvastola ,您遇到的是预期的行为!
我知道一开始很难理解它,但是鉴于中间件堆栈的性质类似于机架堆栈的性质,中间件以相反的顺序遍历以进行响应。
我们的网站上,我们有一张图片来说明这一点,以便于理解。

所以你已经做对了🙌! 通过将:json中间件移到:retry ,您允许响应首先被处理,并且:retry中间件将找到解析的响应主体。

我现在关闭这个,但如果你有任何进一步的问题,请随时跟进

所有4条评论

更新:我确实颠倒了连接配置块中两个中间件的顺序(同时认为“这不可能工作”),现在它可以完美运行。 离开这个是因为我不知道发生了什么,它仍然看起来像一个错误(或者至少应该更好地记录)。

@mvastola ,您遇到的是预期的行为!
我知道一开始很难理解它,但是鉴于中间件堆栈的性质类似于机架堆栈的性质,中间件以相反的顺序遍历以进行响应。
我们的网站上,我们有一张图片来说明这一点,以便于理解。

所以你已经做对了🙌! 通过将:json中间件移到:retry ,您允许响应首先被处理,并且:retry中间件将找到解析的响应主体。

我现在关闭这个,但如果你有任何进一步的问题,请随时跟进

感谢您快速、友好和彻底的解释。 这并不难理解,但在这里有点不直观。 我想知道是否有一种有效的方法可以减少这种情况。

文档

我实际上已经看过你链接的文档,这让我觉得我知道我需要做什么。 (我看到了图片,以及关于“最内层”中间件的内容,但我并没有真正理解这意味着颠倒顺序。)

显示的图像是关于中间件内部的信息,但它可能有助于通过配置块中的顺序如何影响运行顺序的视觉指示来补充它。

配置

除此之外,这个实现还有很多细节让这变得不直观:

  • faraday有三个不同的函数来添加中间件,它们不可互换:每个中间件似乎只能与其中一个一起工作。 这使得看起来好像有三个不同的中间件堆栈(或排序)彼此独立。

  • 这三个不同名称/中间件组的作用非常不清楚,但是,由于大多数中间件 _not_ 运行在请求->响应路径的两端,用户会倾向于假设“请求”任务总是在“响应”之前发生相关的事情。

  • 添加中间件的 rack 关键字use在 Faraday 中(尽我所知)仅适用于那种中间件——同时包装请求和响应的中间件。

无论如何,如果您愿意为此问题调整 API,我很乐意尝试提出一些想法。 否则至少我现在明白了。 我这么说只是因为我可以很容易地看到其他用户在这里遭受同样的困惑。

谢谢@mvastola ,这是无价的反馈🙏!
公平地说,这不是我第一次听说这些事情。

在文档方面,我同意我们还有很长的路要走,因此非常欢迎任何对改进的贡献(实际上最近有一个关于此的讨论主题!)。

配置上的要点也非常有效,我只想说requestresponseuse方法混淆已多次提出,以至于我实际上考虑简单地放弃它们而只使用use ,然后让中间件记录他们将在什么/何时操纵请求/响应。
所以我建议暂时不要推动任何 PR 来更改该 API,但我们非常愿意通过讨论听取社区关于此主题的

此页面是否有帮助?
0 / 5 - 0 等级