Faraday: @handler automatisch auf Faraday.default_adapter setzen, falls nicht angegeben.

Erstellt am 22. Feb. 2012  ·  35Kommentare  ·  Quelle: lostisland/faraday

Normalerweise setzen wir für unsere einfachen Skripte Faraday.default_adapter einmal ganz oben, aber während wir mit Github arbeiten, der (nichts für ungut) Umleitungen liebt, müssen wir faraday_middleware verwenden (naja, nicht verwenden müssen), um Umleitungen zu folgen, was einen Block erfordert (I annehmen) Ich denke, es wäre besser, wenn Faraday davon ausgehen würde, dass der Handler auf Faraday.default_adapater gesetzt werden sollte, wenn er nicht mit use im Block gesetzt ist, dies spart meiner Meinung nach etwas Codierung und redundanten Code.

refactoring

Hilfreichster Kommentar

+1 dazu. Zumindest ein Fehler, dass kein Adapter angegeben wurde, oder besser einfach default_adapter verwenden, wenn nichts angegeben wurde.

Alle 35 Kommentare

Ich bin mir da nicht sicher, werde es aber offen lassen. Der Standardstapel ist UrlEncoded + default_adapter. Wenn Sie Ihren eigenen Stack definieren, sollten Sie ihn zu 100 % definieren, einschließlich des Adapters. Aber es stimmt, dass ich am häufigsten den default_adapter verwende, also könnte es genauso gut ein default sein.

Ich habe darüber nachgedacht, Faraday-Adapter umzugestalten und sie zu Endpunkten anstelle von Middleware zu machen (wie in Nr. 47). Diese Funktion könnte Teil dieser Änderung sein.

:+1: Das hat mich dieses Jahr zum zweiten Mal gebissen. Sie würden denken, ich würde lernen. Wäre schön wenn es behoben wäre.

Kompromiss: Faraday.with_default_stack() , damit wir Seelen gießen, die nur versuchen, Faraday zum ersten Mal zu verwenden, nichts über "den Standardstapel" wissen müssen, nur um Weiterleitungen folgen zu können. Angemessen?

@jbrains Ja, mir ist klar, dass dies benutzerunfreundlich ist. Wir können es so machen, dass ein beschreibender Fehler ausgelöst wird, wenn Sie einen Adapter nicht oder an der falschen Stelle montiert haben.

Ich habe dies in meinem Projekt:

        def faraday_with_default_adapter(base, &block)
          Faraday.new(base) { | connection |
            yield connection
            connection.adapter Faraday.default_adapter
          }
        end

Ich weiß, dass Sie nicht jede Permutation unterstützen wollen, aber es scheint, als würde fast jeder dies irgendwann tun. :) Wenn ich wüsste, wie man das UrlEncoded -Bit hinzufügt (darauf bin ich noch nicht gestoßen), dann würde ich es hier hinzufügen.

Eine Überprüfung im lint -Stil mit beschreibendem Fehler würde sicherlich helfen. Danke. Trotzdem würde uns ein kleines Pokayoke noch mehr helfen.

Ich werde in Erwägung ziehen, Ihnen in Zukunft eine Pull-Anforderung zu senden. Inzwischen, danke.

Dies hat einige Stunden Arbeit gekostet, als ich versucht habe, einen Upload durchzuführen, und den Standardadapter nicht angegeben habe (von dem ich annahm, dass er bereits festgelegt war, da er der Standardadapter ist). Ich habe die Response/Request-Objekte weiter debuggt und untersucht, und es gab überhaupt kein Problem, außer dass mir die gefürchtete Standardadapterzeile fehlte.

Ich denke, dies sollte zumindest irgendwo in der README dokumentiert sein oder mich zumindest warnen, dass ich einen expliziten Adapter benötige.

Danke!

Das hat mich heute auch gebissen mit folgendem Beispiel:

conn = Faraday.new(url: "http://www.example.com") do |faraday|
  faraday.response :json, content_type: /\bjson$/
end

response = conn.get("stuff")

Der Fehler tauchte in faraday_middleware auf, als es versuchte, die Antwortheader abzurufen, als sie nil waren. Ein wenig irreführend. Wurde eine Entscheidung bezüglich der „besten Art“ getroffen, damit umzugehen?

  • Verwenden Sie den Standardadapter, wenn er nicht angegeben ist (der beste IMO)
  • Löst einen Fehler aus, wenn keiner angegeben ist
  • Aktualisieren Sie die README

Über eine PN würde ich mich sehr freuen

Keine Notwendigkeit für eine PR. Wir werden versuchen, dies in der nächsten Version anzugehen.

Danke, @mislav.

Ja, ich habe gestern eine Stunde damit verschwendet, dem hier nachzujagen. Schön zu sehen, dass eine Lösung auf dem Weg ist. Wann wird voraussichtlich die nächste Veröffentlichung erscheinen? Zuletzt war Januar, was eine schrecklich lange Zeit zu sein scheint.

Am Do, 2. Oktober 2014 um 17:49 Uhr, John Carney [email protected]
schrieb:

Wann wird voraussichtlich die nächste Veröffentlichung erscheinen? Der letzte war Januar, wie es scheint
eine schrecklich lange Zeit.

Da 0.8 und 0.9 Feature-Frozen sein sollten, ist der Fix dafür wahrscheinlich
kommen nur in 1.0, wobei ich mir nicht sicher bin, wann es sein wird.

Wie wäre es mit einem einfachen Mittelweg: Wenn versucht wird, eine Anfrage zu stellen, ohne dass ein Adapter vorhanden ist, wird eine Ausnahme ausgelöst.

Oder gibt es einen Anwendungsfall für "Anfragen stellen" ohne Adapter?

Am Fr, 3. Oktober 2014 um 14:07 Uhr, John Bachir [email protected]
schrieb:

Was ist das für ein einfacher Mittelweg: wenn versucht wird, etwas zu machen
eine Anfrage, wenn kein Adapter vorhanden ist, wird eine Ausnahme ausgelöst.

Wie erkennen wir, ob ein Adapter montiert ist?

Beachten Sie, dass ein benutzerdefinierter Adapter, der von jemandem implementiert wurde, dies nicht unbedingt muss
zur Unterklasse Faraday::Adapter.

Ah ich sehe. Da der Adapter ein gleichgeordnetes Element der anderen Middleware ist und die einzige zu testende API die Standard-Rack-API ist, gibt es keine Möglichkeit festzustellen, ob eine Middleware ein HTTP-Adapter ist. :sadposaune:

Wenn dies implementiert ist, können die Änderungen in #496 wahrscheinlich rückgängig gemacht werden (falls sie überhaupt zusammengeführt wurden).

+1 dazu. Zumindest ein Fehler, dass kein Adapter angegeben wurde, oder besser einfach default_adapter verwenden, wenn nichts angegeben wurde.

Der Name ist verwirrend, wenn Sie Middleware hinzufügen müssen, erwarten Sie, dass Sie nur Middleware hinzufügen und die default_adapter beibehalten.

Das ist dumm, dass wir am Ende überhaupt keinen Adapter haben. Das willst du nie...

Ich möchte nur allen versichern, dass wir intern eine Strategie erörtern, um dies zu bewältigen.
Ich weiß, es hört sich nach einer einfachen Prüfung an, aber wie @mislav bereits erklärt hat, haben wir im Moment ein Problem im Zusammenhang mit der Freiheit, Adapter zum Middleware-Stack hinzuzufügen.
Tatsächlich ist ein "Adapter" im Moment nichts anderes als eine Middleware, wie jede andere, die die Anfrage durchführt.
Wenn Sie jetzt Ihren eigenen Middleware-Stack definieren, verlieren wir die Fähigkeit, den Adapter von den anderen Middlewares zu erkennen, es sei denn, Sie verwenden beim Aufbau der Verbindung die Methode #adapter . Leider ist die Verwendung derzeit nicht zwingend erforderlich, wodurch die Adaptererkennung unmöglich wird.

Cool! Danke für den Hinweis hier :)

Am 14. November 2016 um 14:45 Uhr schrieb Mattia [email protected] :

Ich möchte nur allen versichern, dass wir intern eine Strategie diskutieren
um dies zu verwalten.
Ich weiß, es klingt wie eine einfache Prüfung, aber wie
@mislav hat bereits erklärt, dass wir ein Problem bei der haben
Moment im Zusammenhang mit der Freiheit, die Menschen haben, um Adapter in das hinzuzufügen
Middleware-Stapel.
Tatsächlich ist im Moment und "Adapter" nichts anderes als eine Middleware, wie z
jeder andere, der die Anfrage ausführt.
Wenn Sie jetzt Ihren eigenen Middleware-Stack definieren, verlieren wir die Fähigkeit dazu
den Adapter von anderen Middlewares erkennen, es sei denn, Sie verwenden #adapter
Methode beim Verbindungsaufbau. Leider ist die Verwendung davon nicht
derzeit obligatorisch, was die Adaptererkennung unmöglich macht.


Sie erhalten dies, weil Sie kommentiert haben.
Antworten Sie direkt auf diese E-Mail, zeigen Sie sie auf GitHub an oder schalten Sie die stummFaden .

https://v2.developer.pagerduty.com/docs/authentication

Die PagerDuty-API-Dokumentation für ruby+faraday zeigt also dieses Verhalten; Wenn Sie nur ihren Code verwenden, funktioniert es nicht. (Es sei denn, sie reparieren es, was sie wahrscheinlich tun werden, nachdem ich auf das Fehlen eines Adapters hingewiesen habe.)

Ganz ehrlich, mein Vorschlag wäre:

Wenn ich "conn.get" aufrufe und conn keinen Adapter hat, löse eine Ausnahme aus, die mir sagt, dass . Das aktuelle Verhalten besteht darin, sofort zurückzukehren, aber die Dinge nicht auf die Zustände gesetzt zu haben, die Faraday als Ergebnis des Aufrufs von get beschreibt. So ist beispielsweise ".status" immer noch null. Das ist wirklich ein überraschendes Verhalten! Ich würde sagen, dass "Ich kann nichts tun, weil ich keine Ahnung habe, was Sie von mir wollen" wahrscheinlich zu einer Art Diagnose führen sollte.

Hallo @seebs , ich weiß, es klingt albern, aber ich habe erklärt, warum dies nicht so einfach ist, wie es in meinem vorherigen Kommentar erscheinen könnte:

Wenn Sie Ihren eigenen Middleware-Stack definieren, verlieren wir die Fähigkeit, den Adapter von den anderen Middlewares zu erkennen, es sei denn, Sie verwenden beim Aufbau der Verbindung die Methode #adapter. Leider ist die Verwendung derzeit nicht zwingend erforderlich, wodurch die Adaptererkennung unmöglich wird.

Ich habe versucht nachzuvollziehen, was passiert, und mir fehlt etwas.

Wenn Sie das Offensichtliche tun, was so viele Leute tun, und den Adapter nicht angeben, wenn Sie get aufrufen, landen Sie schließlich in build_response von rack_builder, das app.call ausführt. Und ich bin mir nicht sicher, wo das hinführt, weil ich nicht sehe, wo die App eingestellt wurde.

Ich denke, was ich mich frage, ist, wenn Sie nie "adapter :foo" machen, was am Ende den Anruf bekommt?

Eine triviale Lösung:
def initialize(Handler = [])
@handlers = Handler
wenn block_gegeben?

  • self.adapter Faraday.default_adapter
    build(&Proc.neu)
    elsif @handlers.leer?

... Ich denke, das würde funktionieren (-ish)?

Alternativ nach build(&Proc.new) prüfen, ob self.adapter gesetzt ist.

Obwohl adapter :foo die am häufigsten verwendete Methode zum Einrichten des Adapters ist, gibt es andere Möglichkeiten, dies zu tun.
#adapter ist eigentlich nur ein Helfer, aber man kann mit #use einen Adapter in den Stack legen:

conn = Faraday.new(url: "http://www.example.com") do |faraday|
  faraday.response :logger
  faraday.use Faraday::Adapter::NetHttp
end

Was ist denn im Moment ein Adapter? Nichts weiter als eine Middleware, die den Aufruf durchführt und das Ergebnis in env speichert. Deshalb können wir uns nicht einfach darauf verlassen, dass die Methode #adapter aufgerufen wird. Wir können uns nicht auf die Middleware verlassen, die als Adapter fungiert, um von Faraday::Adapter zu erben, da dies auch keine Voraussetzung ist.

Die einzige Lösung besteht darin, die Version Faraday 1.0 zu verwenden, um die Verwendung der Methode #adapter obligatorisch zu machen, oder davon auszugehen, dass sie verwendet wird, und den Standardadapter in den Stack zu verschieben, wenn die Methode nicht aufgerufen wird.

Wir diskutieren intern immer noch darüber, welche die beste Lösung wäre, da wir auf die eine oder andere Weise dazu führen werden, dass die Leute nach dem Update unerwartete Ergebnisse erhalten.
Das passiert vielen Leuten, wenn sie Faraday zum ersten Mal verwenden, stimme ich zu, aber es ist definitiv schlimmer, wenn es auf Ihrem Produktionssystem passiert, nachdem Sie bundle update ausgeführt haben :)

Ich glaube, was ich nicht verstehe, ist ... Wenn Sie nie einen Adapter eingerichtet haben, was führt dann dazu, dass der Anruf bearbeitet und das Ergebnis gespeichert wird? Es gibt einen Aufruf, der, wenn Sie einen Adapter ausgewählt haben, die Methode call() des Adapters verwendet, denke ich. Wenn Sie keinen Adapter ausgewählt haben, welcher Code wird tatsächlich ausgeführt?

Hier habe ich den Adapter ausgewählt, ohne die Methode #adapter zu verwenden.

  faraday.use Faraday::Adapter::NetHttp

Nehmen Sie meinen Ausschnitt aus meinem vorherigen Kommentar und probieren Sie es aus, es wird einfach funktionieren.
Die Sache ist, dass Sie einen Adapter auf viele Arten in den Stack schieben können, und sobald er dort ist, wird er in der Anfrage verwendet (Aufruf der Methode #call ).

Entschuldigung, ich habe mich anscheinend unklar ausgedrückt. Mir ist bewusst, dass Sie einen Adapter auf mehrere Arten auswählen können.

Aber denken Sie an den häufigen Anfängerfehler, keinen Adapter auszuwählen und dann conn.get(...) aufzurufen. Was passiert am Ende eigentlich, außer „nichts, was eine Wirkung hat“?

Ich habe versucht, die Anrufe zu verfolgen, konnte aber nicht herausfinden, was tatsächlich passiert. Es sieht so aus, als hätte Connection einen Standard-Get definiert, der run_request aufruft. Das wiederum ruft build_request und build_response auf, und ich denke, das endet in build_response() von rack_builder, das app.call() aufruft, und es scheint, dass die App ein Response-Objekt generiert, das call() verarbeitet. Aber dann komme ich ins Grübeln. Ich sehe nicht einmal, dass Response eine call()-Methode definiert, und ich kann nicht herausfinden, was letztendlich dazu führt, dass die call()-Methode aufgerufen wird.

Ich gehe davon aus, dass es etwas gibt, das eine Aufrufmethode hat, die aufgerufen wird. Wenn Sie einen Adapter ausgewählt haben, erhalten Sie die Aufrufmethode dieses Adapters. Wenn Sie keinen Adapter ausgewählt haben, woher kommt dann die Aufrufmethode, die tatsächlich ausgeführt wird?

Nach dem Einrichten der Anfrage und der Antwort durchläuft Connection jede Middleware und ruft die Methode call(env) in derselben Reihenfolge auf, in der der Stack gefüllt wird.
Es wird nicht zwischen "normaler Middleware" und dem Adapter unterschieden, es wird lediglich angenommen, dass eine der Middlewares der Adapter ist. Wenn der Stack keine "Adapter-Middleware" enthält, werden alle anderen Middlewares aufgerufen ( call -Methode), aber keine von ihnen führt die Anforderung effektiv aus (das ist die Adapterrolle).
Das bedeutet, dass der Antwort der Status, der Text und alle anderen Felder fehlen, die von der „Adapter-Middleware“ ausgefüllt werden.

Ich verstehe, dass es nicht ganz einfach ist, aber ich hoffe, es ist jetzt klarer 😅

Ah-ha! Das hatte ich nicht verstanden. Es kam mir nicht in den Sinn, dass sie alle call()-Funktionen bereitstellen würden.

Was passiert, wenn der Code nach dem Aufrufen von allem eine Ausnahme ausgelöst hat, wenn der Status nicht festgelegt ist? „StatusNotSetException: Status was not set.

Ich würde wirklich gerne sehen, dass dies behoben wird!

Behoben in #750 @iMacTia – würdest du das schließen?

@olleolleolle ja guter Punkt! Ich dachte, das würde automatisch geschlossen, wenn ich es erwähne :(

Es sieht so aus, als wäre dies nie veröffentlicht worden? Gibt es eine Chance, eine kleinere Version vor 1.0 zu sehen? :Sag nichts böses:

@franzliedke du hast recht, das ist derzeit in v1.0 enthalten und ich stimme zu, dass es vor geraumer Zeit zusammengeführt wurde 😅.
Wir haben jedoch viele Fortschritte in Richtung v1.0 gemacht und ich würde sagen, wir sind ziemlich nah dran, es über die Ziellinie zu bringen.
Gib uns etwas mehr Zeit, das Warten wird sich lohnen 😃

Gut zu hören!

Tut mir leid, dass ich etwas anspruchsvoll rüberkomme – ich weiß, wie stressig Open Source sein kann. Danke für die tolle Software!

Überhaupt nicht @franzliedke !
Schätzen Sie den Anstoß, wir sollten v1.0 wirklich eher früher als später veröffentlichen.
Sehen Sie sich das Repo an, falls Sie es noch nicht getan haben, damit Sie den Start nicht verpassen 👍

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

jedeleh picture jedeleh  ·  3Kommentare

subvertallchris picture subvertallchris  ·  5Kommentare

yusefu picture yusefu  ·  3Kommentare

aleksb86 picture aleksb86  ·  3Kommentare

Lewiscowles1986 picture Lewiscowles1986  ·  4Kommentare