Zum Hauptinhalt springen
Standardmäßig versucht AppSignal, so viele Exceptions (Fehler) wie möglich aufzuzeichnen. Mit unseren Integrationen für viele Frameworks und Hintergrundjob-Gems entgehen nicht viele Exceptions. In den meisten Fällen treten Fehler, die nicht durch Bugs in Ihrem Code verursacht werden, dann auf, wenn Ihre App mit der realen Welt interagiert. Bots schauen vielleicht vorbei und versuchen, Formulare automatisch zu posten; veraltete Links könnten Besucher zu Inhalten leiten, die es nicht mehr gibt usw. Um zu vermeiden, dass diese Fehler als Probleme in AppSignal auftauchen, ist es möglich, Ihrem Code Exception-Handling hinzuzufügen oder AppSignal sogar bestimmte Fehler vollständig ignorieren zu lassen.

Fehler ignorieren

Die AppSignal-Konfiguration ermöglicht es, Fehler zu ignorieren. Indem Sie eine Liste spezifischer Fehler angeben, sendet AppSignal keine Alerts, wenn diese Fehler ausgelöst werden.

Exception-Handling

Einen Fehler einfach zu ignorieren, unterdrückt zwar die Benachrichtigungen, kann jedoch potenziell ein größeres Problem verbergen. Aus diesem Grund empfehlen wir, Ihrer Anwendung Exception-Handling mit begin .. rescue-Blöcken hinzuzufügen. Mit begin .. rescue können Sie bestimmte Exceptions abfangen und einen alternativen Codepfad für den Fall hinzufügen, dass eine Exception auftritt, z. B. das Rendern von 404-Seiten oder das Anzeigen detaillierterer Fehlermeldungen für den Benutzer.
begin
  user = Post.find(1)
rescue RecordNotFound => e
  render :text => "Could not find post", :status => 404
end
Es gibt einige Szenarien, die so behandelt werden sollten, um ordnungsgemäße HTTP-Antworten zu liefern, wenn Ressourcen nicht existieren oder wenn ein Formular-Submit fehlschlägt. Lesen Sie unsere Einführung zu Exception handling für weitere Informationen, wie es funktioniert und wie man es richtig implementiert.

Rails rescue_from

Rails bietet einen Mechanismus, um Exceptions auf Controller-Ebene zu behandeln. Indem Sie eine rescue_from-Anweisung für einen bestimmten Fehler definieren, ist es möglich, einen alternativen Codepfad für den Fall zu erstellen, dass diese Exception ausgelöst wird. Da dies auf jeder Controller-Ebene definiert werden kann, ermöglicht dies, anwendungsweites Exception-Handling hinzuzufügen.
class ApplicationController < ActionController::Base
  rescue_from ActiveRecord::RecordNotFound, :with => :record_not_found

  private

  def record_not_found
    render :text => "404: Resource not found", :status => 404
  end
end
Weitere Informationen zu rescue_from finden Sie im Rails-Guide zu ActionController.

404-Fehler behandeln

Wenn ein Besucher eine URL aufruft, die von Ihrem Routing oder Controller nicht verarbeitet werden kann, lösen Rack und andere Frameworks eine Exception aus. Es ist normalerweise eine gute Idee, diese Exceptions mit einer 404-Antwort für Ihre Benutzer zu behandeln. In Controllern, in denen eine find-Operation basierend auf einem Parameter aus einer URL durchgeführt wird, wird empfohlen, ActiveRecord::RecordNotFound (oder das Äquivalent in Ihrem ORM Ihrer Wahl) zu behandeln, um ebenfalls eine 404-Antwort anzuzeigen. Dies kann jedoch echte Bugs verbergen, daher sollte dies mit Vorsicht geschehen.

Ungültige Authenticity-Tokens behandeln

Rails verfügt über einen Mechanismus, der Ihre Formulare davor schützt, von Bots zu einfach ausgefüllt zu werden. Jedes Mal, wenn ein Formular ohne korrektes Authenticity-Token gepostet wird, wird ein ActionController::InvalidAuthenticityToken ausgelöst. Manchmal können auch legitime Benutzer auf diese Fehler stoßen, daher ist es eine gute Idee, eine separate Fehlerseite zu haben, die erklärt, was schiefgegangen ist. Wir empfehlen, diese Seite mit einer 422-Antwort (Unprocessable Entity) zurückzugeben.

Hacking-Versuche behandeln

Sie erhalten möglicherweise Fehler, weil Bots oder Hacker versuchen, Sicherheitsprobleme wie den berüchtigten YAML-Exploit auszunutzen. Neuere Rails-Versionen werfen einen Hash::DisallowedType, wenn dies passiert. Ein RangeError ist ebenfalls oft ein Resultat eines Hacking-Versuchs. Sie könnten diese Arten von Fehlern abfangen und eine 403-Antwort (Forbidden) zurückgeben.

Exception-Reporting-Helper-Methoden

AppSignal bietet eine einzige Schnittstelle zum Melden von Exceptions mit Appsignal.report_error. Wenn Ihre Anwendung das Ruby-Gem in Version 3 oder älter verwendet, lesen Sie den Abschnitt zur Legacy-Exception-Handhabung.

Appsignal.report_error

Anwendungen können ein Exception-Handling haben, bei dem sie nicht möchten, dass der Ruby-Prozess abstürzt. Durch das Hinzufügen von Exception-Handling steigt die Exception nicht mehr bis zur AppSignal-Instrumentierung auf. AppSignal meldet diese Exceptions nicht. Wenn Sie die Exception melden möchten, ohne dass die Anwendung abstürzt, verwenden Sie den Appsignal.report_error-Helper, um sie aus dem Exception-Handling an AppSignal zu melden. Wenn eine AppSignal-Transaktion aktiv ist, fügt dieser Helper die Exception zur aktuellen Transaktion hinzu. Anwendungen können mehrere Exceptions in einer Transaktion melden. Wenn keine Transaktion aktiv ist, erstellt dieser Helper eine neue Transaktion und meldet die Exception auf der neu erstellten Transaktion. AppSignal meldet die Exception bei Verwendung von Appsignal.report_error immer auf diese Weise.
begin
  # Some code that raises an exception
rescue => error
  Appsignal.report_error(error)
  puts "Exiting. An error occurred: #{error}"
  exit 1
end

Metadaten hinzufügen

Es ist möglich, die Metadaten der Transaktion für die Exception anzupassen, indem Sie einen Block an den Appsignal.report_error-Helper übergeben. Weitere Informationen zu den Datentypen, die in diesem Block hinzugefügt werden können, finden Sie in unseren Leitfäden Tagging und Daten-Anpassung. Die im Block von Appsignal.report_error gesetzten Metadaten gelten nur für die dem Helper übergebene Exception. Außerhalb der Appsignal.report_error-Blöcke gesetzte Metadaten werden allen Exceptions hinzugefügt, falls eine aktive Transaktion vorhanden ist.
begin
  # some code
rescue => error
  Appsignal.report_error(error) do
    Appsignal.set_namespace("admin")
    Appsignal.set_action("MyCustomAction#perform")
    Appsignal.add_params(:param1 => "value1", :param2 => "value2")
    Appsignal.add_tags(:tag1 => "value1", :tag2 => "value2")
    Appsignal.add_custom_data(
      :i18n => {
        :locale => "en_GB",
        :default_locale => "en_US"
      }
    )
  end
end

Mehrere Exceptions melden

In einer Transaktion können mehrere Fehler gemeldet werden, z. B. bei einer Rails-Controller-Action, die einen HTTP-Request behandelt, oder bei einem Sidekiq-Hintergrundjob. Maximal 10 Fehler können auf einer Transaktion gesetzt werden. Wenn mehrere Exceptions in einer Transaktion gemeldet werden, gelten die im Block von Appsignal.report_error gesetzten Metadaten nur für die dem Helper übergebene Exception. Außerhalb der Appsignal.report_error-Blöcke gesetzte Metadaten werden allen Exceptions hinzugefügt.
def index
  # This tag is added to all exceptions
  Appsignal.add_tags(:some_tag_for_all_errors => true)

  begin
    raise "something went wrong"
  rescue => error
    # Report the first exception
    Appsignal.report_error(error) do
      # This tag is only added to the first exception
      Appsignal.add_tags(:some_tag => true)
    end
  end

  begin
    raise "something else went wrong"
  rescue => error
    # Report the second exception
    Appsignal.report_error(error) do
      # This tag is only added to the second exception
      Appsignal.add_tags(:other_tag => true)
    end
  end

  # This tag is added to all exceptions
  Appsignal.add_tags(:another_tag_for_all_errors => true)
end

Exceptions melden, die einen Prozess abstürzen lassen

Standardmäßig meldet AppSignal Exceptions, die einen Ruby-Prozess zum Absturz bringen, solange AppSignal vor dem Auftreten der Exception gestartet wurde.
# some_script.rb
require "appsignal"

Appsignal.start

raise "I will crash the process!"
Um diese Funktionalität zu deaktivieren, setzen Sie die enable_at_exit_reporter-Konfigurationsoption auf false.

Kurzlebige Ruby-Prozesse

Wenn Sie Exceptions aus Ruby-Skripten, Rake-Tasks oder kurzlebigen Ruby-Prozessen melden, lesen Sie die Dokumentation auf diesen Seiten dazu, wann Appsignal.stop am besten aufgerufen werden sollte, um sicherzustellen, dass alle Exceptions an AppSignal gemeldet werden.

Legacy-Exception-Handhabung

Lesen Sie diesen Abschnitt, wenn Sie das AppSignal für Ruby-Gem in Version 3 oder älter verwenden. Für neuere Versionen unseres Ruby-Gems verwenden Sie den Appsignal.report_error-Helper. AppSignal bietet zwei Exception-Reporting-Helper-Methoden, welche Sie verwenden, hängt vom Kontext des Fehlers ab. Die Methoden sind:
  • set_error: Der set_error-Helper setzt den Fehler auf der aktuell aktiven Transaktion. Wenn keine Transaktion aktiv ist, wird kein Fehler gemeldet. Das Setzen eines Fehlers auf der aktuell aktiven Transaktion überschreibt jeden zuvor auf der Transaktion gesetzten Fehler.
  • send_error: Verwenden Sie send_error, um Fehler zu melden, wenn keine AppSignal-Transaktion aktiv ist.

Appsignal.set_error

Es gibt Szenarien, in denen Sie Ihr eigenes Exception-Handling haben und nicht möchten, dass der Ruby-Prozess abstürzt. Durch das Hinzufügen Ihres eigenen Exception-Handlings wird der Fehler nicht mehr an die AppSignal-Integration weitergeleitet und somit nicht automatisch aufgezeichnet. Wenn Sie den Fehler dennoch verfolgen möchten, können Sie Appsignal.set_error verwenden, um die Exception zur aktuellen AppSignal-Transaktion hinzuzufügen. Der Fehler wird in AppSignal aufgezeichnet, aber Ihr Prozess wird nicht abstürzen.
require "yaml"
class SomeClass
  def call
    YAML.load(File.read("config.yml"))
  rescue SystemCallError => exception
    Appsignal.set_error(exception)
    puts "No config file found. Using defaults."
  end
end
Die Exception wird von AppSignal wie jeder andere Fehler verfolgt, und es ermöglicht Ihnen, eigene Fehlerbehandlung und Fallbacks bereitzustellen. Der Aufruf von set_error funktioniert nur, wenn eine AppSignal-Transaktion aktiv ist. Andernfalls wird der Fehler ignoriert. Eine Transaktion ist in den meisten unserer automatisch unterstützten Integrationen und bei Verwendung von Appsignal.monitor oder Appsignal.monitor_transaction aktiv. Weitere Informationen darüber, wann Appsignal.monitor_transaction zu verwenden ist, finden Sie in unserem Leitfaden zur Instrumentierung für Skripte und Hintergrundjobs. Siehe Appsignal.send_error zum Senden von Fehlern ohne eine AppSignal-Transaktion.
require "yaml"

Appsignal.monitor :action => "My action" do
  begin
    YAML.load(File.read("config.yml"))
  rescue SystemCallError => exception
    Appsignal.set_error(exception)
    puts "No config file found. Using defaults."
  end
end

Appsignal.send_error

AppSignal bietet einen Mechanismus, um Fehler an AppSignal zu senden, ohne eine Transaktion starten zu müssen. Dies ist nützlich, um Fehler zu verfolgen, die in Code auftreten, der nicht in einem Web- oder Hintergrundjob-Kontext steht, wie z. B. separate Rake-Tasks oder Ruby-Skripte. Dies ist nützlich für Instrumentierung, die nicht automatisch AppSignal-Transaktionen zum Profilen erstellt, wie unsere Integrationen. Sie können die Methode Appsignal.send_error verwenden, um eine Exception von einer beliebigen Stelle in Ihrem Code direkt an AppSignal zu senden, ohne zuerst eine AppSignal-Transaktion mit Appsignal.monitor zu starten.
begin
  # some code
rescue => e
  Appsignal.send_error(e)
end

Metadaten hinzufügen

In AppSignal für Ruby-Gem 2.9 und neuer kann ein zusätzlicher Block an die Appsignal.send_error-Methode übergeben werden, um der Fehler-Transaktion mehr Metadaten hinzuzufügen. Dazu gehören Metadaten wie der Action-Name und Parameter. Ältere Versionen des Ruby-Gems erlauben es nicht, zusätzliche Metadaten zu setzen.
begin
  # some code
rescue => e
  Appsignal.send_error(e) do |transaction|
    transaction.set_action("my_action")
    transaction.set_namespace("my_namespace")
    transaction.params = { :time => Time.now.utc }
  end
end

Appsignal.listen_for_error

Dieser Helper wurde in Ruby-Gem-Version 4 entfernt. Verwenden Sie stattdessen einen Ruby-rescue-Block mit dem Appsignal.report_error-Helper.
Eine alternative Möglichkeit, Fehler mit AppSignal zu verfolgen, besteht darin, Code, der eine Exception auslösen könnte, in einen listen_for_error-Block einzuwickeln. Wenn eine Exception innerhalb dieses Blocks ausgelöst wird, wird sie automatisch von AppSignal verfolgt und erneut ausgelöst. Dadurch können die Anwendung und Frameworks die Exception wie gewohnt behandeln.
require "rake"
require "appsignal"

task :fail do
  Appsignal.listen_for_error do
    raise "I am an exception in a Rake task"
  end
end