Faraday: Al intentar registrar el cuerpo de la solicitud, registra la respuesta en su lugar

Creado en 14 jul. 2016  ·  14Comentarios  ·  Fuente: lostisland/faraday

Hola.

Estoy tratando de hacer que 0.9.2 imprima los cuerpos de solicitud y respuesta.
Esto no está documentado, pero se discute en el #277 PR.
Creo que he hecho la configuración adecuada. Estoy usando Faraday a través de Saorin..

  <strong i="9">@client</strong> = Saorin::Client.new(:url => @endpoint) do |connection|
    connection.response :logger, <strong i="10">@logger</strong>, :bodies => true
  end

A mi parecer, la salida de depuración no imprime el cuerpo de la solicitud , pero imprime el cuerpo de la respuesta (no se espera).
(y sigue imprimiendo el cuerpo de la respuesta nuevamente, como se esperaba).

Así que obtengo algo así en el registro: (tenga en cuenta el valor de request . Es un duplicado de response en realidad.

post https://foo.bar.com/api/3.0/json-rpc
request User-Agent: "Faraday v0.9.2"
Content-Type: "application/json"
request {"result":{"accessGranted":false},"id":"foo","jsonrpc":"2.0"}
Status 200
response server: "nginx"
date: "Thu, 14 Jul 2016 21:28:21 GMT"
content-type: "application/json"
transfer-encoding: "chunked"
connection: "close"
response {"result":{"accessGranted":false},"id":"foo","jsonrpc":"2.0"}

Verifique este código de faraday/response/logger.rb :

    def call(env)
      info "#{env.method} #{env.url.to_s}"
      debug('request') { dump_headers env.request_headers }
      debug('request') { dump_body(env[:body]) } if env[:body] && log_body?(:request)
      super
    end

    def on_complete(env)
      info('Status') { env.status.to_s }
      debug('response') { dump_headers env.response_headers }
      debug('response') { dump_body env[:body] } if env[:body] && log_body?(:response)
    end

Si lo leí correctamente, la línea: debug('request') { dump_body(env[:body]... no imprime la var adecuada.

Y, en realidad, al inspeccionar env[] , no puedo encontrar el cuerpo de la solicitud en ninguna parte :-( Solo request_headers , request_options y response datos.

Dado que no creo que nadie se haya dado cuenta de eso antes, es probable que haya cometido algún error. ¿Pero donde?

unconfirmed

Comentario más útil

Hola @iMacTia , también me quedé con este problema. Descubrí que ese problema se reproduce cuando define el adaptador antes que el registrador.

Este cuerpo de solicitud de registro de código:

Faraday.new(url: url) do |faraday|
  faraday.response :logger, ::Logger.new(STDOUT), bodies: true
  faraday.adapter Faraday.default_adapter
end

Esto no:

Faraday.new(url: url) do |faraday|
  faraday.adapter Faraday.default_adapter
  faraday.response :logger, ::Logger.new(STDOUT), bodies: true
end

Todos 14 comentarios

@nthx Estoy viendo esto también...

@stve : ¿el informe tiene sentido para usted?

¿Quizás también necesita configuración de solicitud? aunque eso no lo he probado..

<strong i="6">@client</strong> = Saorin::Client.new(:url => @endpoint) do |connection|
  connection.response :logger, <strong i="7">@logger</strong>, :bodies => true
  connection.request :logger, <strong i="8">@logger</strong>, :bodies => true
end

Es una condición de carrera estándar, creo. Lo que sucede aquí es que env[:body] se configuró una vez en el cuerpo de la solicitud. Pero en el momento en que se ejecuta el método de registro o dump_body, el cuerpo de la respuesta ha reemplazado el cuerpo de la solicitud dentro env[:body] y no se realizan más variables/copias del cuerpo de la solicitud original, no es que necesariamente solucione las cosas. env es global para la solicitud, no debemos asumir que el middleware se está ejecutando sincrónicamente y en orden antes de realizar la llamada.

Una solución sencilla sería utilizar dos valores de env para realizar un seguimiento de los cuerpos, uno para la solicitud y otro para la respuesta.

No tenemos este error con los encabezados porque hay dos valores separados allí: request_headers y response_headers . Entonces, ¿por qué no seguir su ejemplo...

Alternativamente, crea un segundo env llamado request_body y almacena el cuerpo de la solicitud dos veces en env.request_body y env.body . De esa manera, cualquier código que se base en el comportamiento existente lo mantiene, pero el código actualizado, como nuestra función de registro aquí, puede usar request_body si existe.

Si esto no se soluciona pronto, es muy probable que parchee Faraday y use mi propia bifurcación. No puedo tener un registro no confiable...

@nthx , lo siento si me lo perdí, pero ¿qué registrador estás usando?
El código se ve bien, el único "problema" que puedo ver es con los procesos utilizados para evaluar el mensaje. Por lo general, esto no es un problema, a menos que su evaluación ocurra DESPUÉS de que se procese la solicitud.
No estoy seguro de que esto sea posible con el registrador estándar (síncrono), así que me gustaría saber cuál estás usando :)

En realidad, he estado usando mi propio registrador en este caso. Ha funcionado para otros mensajes, así que no pensé que pudiera causar un problema.
Verificaré con el registrador estándar y volveré a verificar el mío, y se lo haré saber.

Hola @nthx , ¿tuviste suerte con tus pruebas? ¿Descubriste algo nuevo?
Me gustaría cerrar este problema y entender si el problema radica en Faraday o en el registrador.

Voy a cerrar esto asumiendo que la falla está en el registrador ya que probé el estándar y funciona bien para mí.

@nthx siéntase libre de reabrir en caso de que tenga alguna evidencia nueva que apunte a Faraday como la posible causa

Todavía tenía este error, usaba el registrador incorporado de Faraday en ese momento, pero lo resolví escribiendo mi propio registrador en el software intermedio y luego cambié de usar Faraday a algo más simple.

Hola @iMacTia , también me quedé con este problema. Descubrí que ese problema se reproduce cuando define el adaptador antes que el registrador.

Este cuerpo de solicitud de registro de código:

Faraday.new(url: url) do |faraday|
  faraday.response :logger, ::Logger.new(STDOUT), bodies: true
  faraday.adapter Faraday.default_adapter
end

Esto no:

Faraday.new(url: url) do |faraday|
  faraday.adapter Faraday.default_adapter
  faraday.response :logger, ::Logger.new(STDOUT), bodies: true
end

Hola @llxff ,

sí, eso es de esperar, ya que el orden de los middlewares es fundamental y el adaptador siempre debe estar en la parte inferior.
Si coloca el adaptador ANTES, la solicitud se realizará antes de que se alcance el adaptador del registrador, lo que provocará que la respuesta se registre dos veces.
Además, ahora estoy leyendo el problema de @nthx con esto y me di cuenta de que le falta el adaptador en su pila de middleware:

<strong i="11">@client</strong> = Saorin::Client.new(:url => @endpoint) do |connection|
    connection.response :logger, <strong i="12">@logger</strong>, :bodies => true
  end

También revisé el código en la gema Saorin y se ve completamente incorrecto exactamente por la misma razón: https://github.com/mashiro/saorin/blob/master/lib/saorin/client/faraday. rb#L16

Tiene sentido. Todavía no puedo verificarlo nuevamente, pero tenga otro pensamiento ... He leído mi informe inicial y dice:

Esto no está documentado, pero se discute en el #277 PR.

¿Sigue siendo así, que no hay documentación sobre cómo configurar realmente el registro de respuestas?
Si los documentos estuvieran allí, entonces no habría dudas sobre cómo hacerlo.

¿Puede crear un ticket para actualizar los documentos? ¿O reabrir este tal vez?

Además, ¿quién debería contactar a los chicos de Saorin?

Hola @nthx , tienes mucha razón, nuestra documentación actualmente no es lo suficientemente detallada (en realidad, estamos usando el archivo Léame como "documentación").
En su caso específico, está el tercer ejemplo en la sección https://github.com/lostisland/faraday/blob/master/README.md#basic -use que muestra cómo usar el middleware del registrador, pero estoy de acuerdo con que no es suficiente .
Estamos planeando tener un Wiki renovado en un futuro cercano que debería ayudar a mitigar este tipo de problemas.

Según Saorin, le sugiero que abra un problema en su página proporcionando ejemplos con el código que falla e informando mi comentario, lo que debería ayudarlos a rastrear el problema.
Prefiero que hagas esto ya que estás usando activamente su gema y aunque podrás proporcionar cualquier información adicional que puedan necesitar.

Gracias

Hola,

Acabo de ver este problema y entiendo por qué mi solicitud no estaba bien firmada.

Creamos un middleware que agrega una firma antes de realizar la solicitud.
Como definimos el adaptador antes de usar el middleware, la solicitud se envió antes de agregar el encabezado de autorización.

El efecto secundario fue que el middleware estaba usando env.body para construir la firma y, por lo tanto, estaba usando el cuerpo de respuesta para construir la firma.

Mientras definía el adaptador en la parte superior de la conexión, mis registros también eran incorrectos y pensaba que mi script de firma también era incorrecto.

¡Atentamente!

¿Fue útil esta página
0 / 5 - 0 calificaciones