Sentry-javascript: Rückgabe einer Zusage von den wichtigsten API-Capture*-Methoden

Erstellt am 3. Mai 2019  ·  16Kommentare  ·  Quelle: getsentry/sentry-javascript

Ist dies garantiert, dass die Ausnahme Sentry gemeldet wird?

try {
  // code
} catch (e) {
  const eventId = Sentry.captureException(e);
  console.log('sentry event', eventId);
  process.exit(1);
}

Die Dokumentation ist nicht klar, ob die Ereignis-ID lokal oder remote generiert wird. Ist Ablassen überhaupt relevant? https://docs.sentry.io/error-reporting/configuration/draining/?platform=node

Breaking Documentation Improvement

Hilfreichster Kommentar

Wir haben seit dem Upgrade auf @sentry/node ziemliche Probleme mit Sentry. Wir werden wahrscheinlich zu raven-node bis es eine bessere Lösung gibt.

Am Ende jeder serverlosen Ausführung Warteschlangen bei willkürlichen Timeouts leeren zu müssen, fühlt sich definitiv eher wie ein Hack an und keine Lösung. 🤔.

Alle 16 Kommentare

Danke für die Hervorhebung, um klarzustellen, dass es nicht vollständig synchron ist, der "Transport" läuft im Hintergrund. Es ist also streng genommen nicht garantiert, dass das Ereignis Sentry trifft.

Das eventId wird lokal im SDK generiert und verwendet, um das Ereignis auf dem Server aufzunehmen.

Wir werden unsere Dokumente aktualisieren, um dies zu verdeutlichen.

Ok, also nur zur Verdeutlichung, es ist in der Tat notwendig, das hier beschriebene umzusetzen: https://docs.sentry.io/error-reporting/configuration/draining/?platform=node

Ist das richtig, @HazAT?

@rhyek Corrent, wenn Sie sicherstellen möchten, dass alles gesendet wird, können Sie auf Flush warten, um sicherzustellen, dass alles gesendet wird.

Wäre es nicht besser, einfach das Versprechen der capture* Methoden offenzulegen? API wäre klarer, da die Rückgabe eines Versprechens die Benutzer wissen lässt, dass sie await es tun müssen, um sicherzustellen, dass das Ereignis gesendet wird, oder einfach nur darauf hoffen, dass es gesendet wird. Sowohl close als auch flush sind Methoden von mehrdeutigem Nutzen, die versuchen, etwas synchron zu machen, das bisher als asynchron angesehen wurde. Außerdem sind diese beiden Methoden völlig kaputt: Tatsächlich gibt es einige Macken (ich würde sagen, dass es ein Bug ist, aber das hängt wahrscheinlich vom POV der Person ab, die sie betrachtet):

  • der Zweck von timeout das an flush ist null, da es vom Transport nicht respektiert wird, indem das Senden der Anforderungen unterbrochen wird. Es löst nur das zurückgegebene Promise auf false wenn der Timer abläuft. Ich frage mich immer noch nach dem Nutzen eines solchen Codes und Verhaltens...
  • die Methode flush gibt bei jedem Aufruf ein neues Promise zurück, das aufgelöst wird, sobald timeout erreicht ist. Es gibt zwei Probleme: Der gesamte von setInterval ausgeführte Code ist, zumindest in meinen Tests in der Konsole des Browsers, extrem langsam, und das Versprechen löste sich viele Sekunden nach Ablauf des Timeouts. Das zweite und wichtigere Problem ist, dass der Code der Funktion _isClientProcessing das Timeout bei jedem Aufruf löscht. Wenn also jemand etwas wie Promise.all([fush(), flush()]) tut (ich weiß nicht, warum er das tun sollte) es, aber da die API jedes Mal ein neues Versprechen zurückgibt, wenn er versucht sein könnte, es zu tun), wird dieses Versprechen nie gelöst.

Korrent, wenn Sie sicherstellen möchten, dass alles gesendet wird, können Sie auf Flush warten, um sicherzustellen, dass alles gesendet wird.

Falsch, siehe meine obigen Punkte, um zu verstehen, warum Sie nicht sicher sein können, ob alles gesendet wird, selbst wenn Sie auf den Flush warten. Ich würde sagen, dass ein solches API-Design völlig kaputt ist und ich kann nicht wirklich verstehen, warum nicht dem Benutzer die Wahl überlassen wird, auf die Versprechen zu warten, die das Senden eines Ereignisses darstellen, anstatt zu versuchen, eine Shutdown-API zu bauen, die nicht einmal für alle funktionieren kann Sprachen, in denen Unified API funktionieren soll

Ich denke, Zugang zu einem Versprechen zu haben, das sich auflöst, wenn das Ereignis endlich ist
zusätzlich zu den anderen in diesem Thread beschriebenen Methoden verschickt macht a
viel sinn.

Am Sa, 11. Mai 2019, 12:29 Uhr Stefano Arlandini [email protected]
schrieb:

Wäre es nicht besser, einfach das Versprechen aus der Aufnahme zu enthüllen*
Methoden? API wäre klarer, da die Rückgabe eines Versprechens die Benutzer darüber informiert.
Sie müssen darauf warten, um sicherzustellen, dass das Ereignis gesendet wird oder einfach nur
Feuer-und-Vergiss, in der Hoffnung, dass es gesendet wird. Sowohl Close als auch Flush sind Methoden der
mehrdeutiges Dienstprogramm, das versucht, etwas Gewesenes synchron zu machen
denken, asynchron zu sein. Außerdem sind diese beiden Methoden völlig kaputt: in
Tatsächlich gibt es einige Macken (ich würde sagen, dass es ein Bug ist, aber
wahrscheinlich hängt dies vom POV der Person ab, die sie ansieht):

  • Der Zweck des an flush übergebenen Timeouts ist null, da es nicht der Fall ist
    vom Transport respektiert, indem das Senden der Anfragen unterbrochen wird. Es
    löst das zurückgegebene Promise einfach auf false auf, wenn der Timer abläuft.
    Ich frage mich immer noch nach dem Nutzen eines solchen Codes und Verhaltens...
  • die Methode flush gibt jedes Mal ein neues Promise zurück, wenn sie so heißt
    wird behoben, sobald der Timeout erreicht ist. Es gibt zwei Probleme:
    der gesamte von setInterval ausgeführte Code ist extrem langsam, zumindest in
    meine Tests in der Konsole des Browsers, und das Versprechen löste viele
    Sekunden nach Ablauf des Timeouts. Das zweite und wichtigere Problem ist
    dass der Code der Funktion _isClientProcessing den Timeout löscht
    jedes Mal, wenn es aufgerufen wird, also wenn jemand etwas wie Promise.all([fush(),
    flush()]) (Ich weiß nicht, warum er es tun sollte, aber da die API zurückkehrt
    jedes Mal ein neues Versprechen, wenn er versucht sein könnte, es zu tun), dann wird ein solches Versprechen
    nie gelöst werden.

Korrent, wenn Sie sicherstellen möchten, dass alles gesendet wird, können Sie auf Flush warten
um sicherzustellen, dass alles gesendet wird.

Falsch, siehe meine Punkte oben, um zu verstehen, warum man überhaupt auf die Spülung wartet
kann nicht sicher sein, dass alles gesendet wird. Ich würde sagen, dass ein solches API-Design ist
total kaputt und ich kann nicht wirklich verstehen, warum das nicht dem Benutzer überlassen wird
Wahl, auf die Versprechen zu warten, die das Senden eines Ereignisses darstellen
anstatt zu versuchen, eine Shutdown-API zu erstellen, die nicht einmal für alle funktionieren kann
Sprachen, in denen Unified API funktionieren soll


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/getsentry/sentry-javascript/issues/2049#issuecomment-491533914 ,
oder den Thread stumm schalten
https://github.com/notifications/unsubscribe-auth/AAFLTSVSICZ7Y26UHCSMKWLPU4GATANCNFSM4HKUJ5ZQ
.

Ich würde auch sagen, dass ich nicht erwarte, dass eine Methode, die ein Ergebnis zurückgibt, etwas im Hintergrund ausführt, da dies für die Benutzer eine Quelle der Verwirrung ist (und natürlich die Hauptfrage dieses Problems). Wenn stattdessen ein Versprechen zurückgegeben wird, ist es nur ein Platzhalter für etwas, das in Zukunft kommen wird und noch nicht fertig ist. Die Wahl, darauf zu warten oder es einfach abzufeuern und zu vergessen, liegt offensichtlich beim Benutzer. Da die Ereignis-ID lokal generiert wird (ich sehe übrigens keinen Grund, dies zu tun), können Sie etwas verwenden (weil es sofort zurückgegeben wird), das nicht gültig ist, weil der Transport das Ereignis aus irgendeinem Grund nicht senden konnte und Sie nicht weiß nicht einmal davon

Wir haben seit dem Upgrade auf @sentry/node ziemliche Probleme mit Sentry. Wir werden wahrscheinlich zu raven-node bis es eine bessere Lösung gibt.

Am Ende jeder serverlosen Ausführung Warteschlangen bei willkürlichen Timeouts leeren zu müssen, fühlt sich definitiv eher wie ein Hack an und keine Lösung. 🤔.

Für diejenigen, die nach weiteren Beispielen suchen, was funktionieren könnte – ich fand einige der Lösungen in #1449 hilfreich zum Spülen und dergleichen, sie diskutieren auch viel zu diesem Problem.

(Sie konzentrieren sich auf Lambdas und Serverless, aber die gleichen Konzepte würden wahrscheinlich auch in anderen Umgebungen funktionieren, da es sich um den Flushing-Ansatz handelt).

Ich bin auf jeden Fall daran interessiert, dass es irgendwann einen besseren Weg gibt, bei dem nicht jedes Mal gespült wird.

Stimme voll und ganz dem zu, was in diesem Thread gesagt wird, IMO ist es wirklich verwirrend, eine synchrone Methode zu haben, die Asynchronität im Hintergrund verbirgt.
Vielleicht hat das Wachteam einen sehr guten Grund, dies so zu tun, trotzdem wäre ein Update der Dokumentation sehr dankbar.

@cibergarri Ich denke, der Grund dafür ist, dass die eventId sofort zurückgegeben werden kann, ohne den Userland-Code bei einem potenziell langsamen Netzwerkaufruf an Sentry-APIs zu blockieren. Ich stimme zu, dass es verwirrend ist, einen Wert von einer asynchronen API zurückzugeben und möglicherweise zu einem stillen Verlust von Fehlern in serverlosen Ausführungskontexten führt, die für die asynchronen Transportschichtaufrufe nicht lange genug bestehen bleiben. Eine Lösung wäre, die Funktion in zwei Teile aufzuteilen, sodass ein Benutzer sich für asynchrones Verhalten entscheiden muss, z

Sentry.captureException() // -> returns eventId after successful submission to sentry
Sentry.captureExceptionAsync() // -> returns promise

Oder als Parameter, zB

Sentry.captureException(ex, {async: false}) // ->  default, returns eventId after successful submission to sentry
Sentry.captureException(ex, {async: true}) // -> returns promise

Die Ereignis-ID wird immer im Client generiert, daher spielt die Async- oder Sync-API keine Rolle und folglich ist sie kein guter Indikator dafür, ob ein Ereignis wirklich gesendet wurde oder nicht (ein weiteres Problem imo). Ich habe auch vor langer Zeit für das PHP-SDK eine ähnliche Lösung vorgeschlagen, die sowohl synchrone als auch asynchrone Methoden für jede capture* Methode beinhaltete, aber sie wurde abgelehnt. Ich habe den wahren Grund nicht ganz verstanden, warum Unified API Asynchronität verbergen will und Entwickler kein Versprechen preisgeben wollen, aber es schien mir, dass sie nicht so offen waren, dies zu ändern.

Leider hat mich dieses Problem dazu veranlasst, von Sentry abzuweichen, da es Tracking-Fehler in serverlosen Umgebungen zu fehleranfällig machte. (Oh die Ironie.)

capture*Async Methoden wären super hilfreich gewesen

Können wir dazu ein Update bekommen?

@marcospgp was

Ich denke, abgesehen von dieser Dokumentation ist aus den Reaktionen auf Kommentare und den Kommentaren selbst ziemlich klar, dass Benutzer gerne Zugriff auf die Versprechen haben möchten, und es gibt keinen guten Grund, dies imho nicht zuzulassen

Leider wird dies nicht vor der Veröffentlichung von v6 geschehen, da es eine bahnbrechende Änderung unserer Haupt-APIs darstellt und viele Änderungen erfordern würde. Ich werde dies jedoch der Roadmap hinzufügen, um dies zu beachten.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen