Sollevare e salvare le eccezioni in Ruby

Come sollevare e salvare le eccezioni in Ruby

Le eccezioni sono una parte fondamentale della programmazione in Ruby, in quanto consentono agli sviluppatori di gestire gli errori con grazia e di garantire applicazioni robuste e tolleranti agli errori. Il meccanismo di gestione delle eccezioni di Ruby è intuitivo ma potente e consente agli sviluppatori di sollevare errori quando qualcosa va storto e di salvarli per evitare crash dell'applicazione. In questa guida di 2000 parole, esploreremo come sollevare e salvare le eccezioni in Ruby, coprendo le basi, le tecniche avanzate, le migliori pratiche e gli esempi reali.

Cosa sono le eccezioni in Ruby?

Le eccezioni in Ruby sono oggetti che rappresentano errori o condizioni inattese durante l'esecuzione del programma. Quando si verifica un errore, come il tentativo di dividere per zero, l'accesso a un file inesistente o un errore di rete, Ruby solleva un'eccezione. Se non viene gestita, l'eccezione fa terminare il programma con un messaggio di errore.

Il sistema di eccezioni di Ruby è costruito attorno all'elemento Eccezione che funge da radice della gerarchia delle eccezioni. Sottoclassi come StandardError, RuntimeError, ArgumentError, E NoMethodError gestire tipi specifici di errori. Gli sviluppatori possono anche definire classi di eccezioni personalizzate per rappresentare errori specifici dell'applicazione.

La gestione delle eccezioni in Ruby ruota attorno a due azioni chiave:

  • Innalzamento: Attivazione di un'eccezione quando si verifica un errore.
  • Salvataggio: Catturare e gestire le eccezioni per evitare gli arresti anomali del programma.

Vediamo come sollevare e salvare le eccezioni in modo efficace.

Sollevare eccezioni in Ruby

Sollevare un'eccezione è il processo di segnalazione di un errore o di una condizione inaspettata. Ruby fornisce l'opzione aumento (e il suo alias fallire) per attivare le eccezioni.

Il aumento Metodo

Il modo più semplice per sollevare un'eccezione è usare l'opzione aumento senza argomenti, che solleva un problema di Errore di runtime (una sottoclasse di Errore standard):

rubino
sollevare
# => RuntimeError: eccezione non gestita

Si può anche fornire un messaggio di errore:

rubino
raise "Qualcosa è andato storto!"
# => RuntimeError: Qualcosa è andato storto!

Per sollevare una classe di eccezione specifica, passare la classe come primo parametro e il messaggio come secondo:

rubino
sollevare ArgumentError, "Input non valido fornito".
# => ArgumentError: Input non valido fornito

Classi di eccezioni personalizzate

Per applicazioni più complesse, è possibile definire classi di eccezioni personalizzate per rappresentare errori specifici. Le eccezioni personalizzate ereditano da Errore standard o una delle sue sottoclassi, per garantire la compatibilità con il comportamento di salvataggio predefinito di Ruby.

Esempio:

rubino
classe AuthenticationError  AuthenticationError: Credenziali non valide

Definendo Errore di autenticazioneè possibile gestire gli errori legati all'autenticazione separatamente dagli errori generici.

Sollevare eccezioni con causa

Ruby consente di allegare una "causa" a un'eccezione, utile per il debug. La causa è l'eccezione originale che ha portato a quella attuale. Utilizzate l'opzione eccezione per accedervi:

rubino
iniziare
  raise "Errore originale"
rescue => e
  raise "Nuovo errore" # L'errore originale è conservato come causa
fine

È possibile verificare la causa con e.causa:

rubino
iniziare
  iniziare
    raise "Errore originale"
  rescue => e
    sollevare "Nuovo errore"
  fine
salvataggio => e
  mette e.message # => Nuovo errore
  puts e.cause.message # => Errore originale
fine

Salvataggio delle eccezioni

Il salvataggio delle eccezioni consente di catturare e gestire gli errori con grazia, evitando che il programma si blocchi. Ruby utilizza il metodo inizio/soccorso per gestire le eccezioni.

Il inizio/soccorso Blocco

La struttura di base di un inizio/soccorso Il blocco è:

rubino
iniziare
  # Codice che potrebbe sollevare un'eccezione
salvataggio
  # Gestire l'eccezione
fine

Esempio:

rubino
iniziare
  risultato = 10 / 0
salvataggio
  mette "Si è verificato un errore!"
fine
Uscita #: Si è verificato un errore!

Per impostazione predefinita, soccorso catture Errore standard e le sue sottoclassi. Se non si specifica una classe di eccezione, è equivalente a salvataggio StandardError.

Gestione di eccezioni specifiche

Per gestire eccezioni specifiche, specificare la classe di eccezione nel parametro soccorso clausola:

rubino
iniziare
  risultato = 10 / 0
salvataggio ZeroDivisionError
  puts "Impossibile dividere per zero!"
salvataggio ArgumentError
  mette "Argomento non valido fornito!"
fine
# Uscita: Impossibile dividere per zero!

È anche possibile catturare l'oggetto dell'eccezione per un'ulteriore verifica:

rubino
iniziare
  raise ArgumentError, "Input non valido"
salvataggio ArgumentError => e
  mette "Errore: #{e.message}".
fine
Uscita #: Errore: Ingresso non valido

Utilizzando altro E garantire

Ruby fornisce due clausole aggiuntive per la gestione delle eccezioni:

  • altro: Esegue se non viene sollevata alcuna eccezione.
  • garantire: Esegue indipendentemente dal verificarsi di un'eccezione, utile per le operazioni di pulizia.

Esempio:

rubino
inizia
  mette "Esecuzione dell'operazione..."
  risultato = 10 / 2
salvataggio ZeroDivisionError
  puts "Impossibile dividere per zero!"
else
  puts "Operazione riuscita: #{risultato}"
assicura
  mette "Pulizia..."
fine
# Uscita:
# Esecuzione dell'operazione...
# Operazione riuscita: 5
# Pulizia...

Se si verifica un'eccezione:

rubino
inizia
  mette "Esecuzione dell'operazione..."
  risultato = 10 / 0
salvataggio ZeroDivisionError
  puts "Impossibile dividere per zero!"
else
  puts "Operazione riuscita: #{risultato}"
assicura
  mette "Pulizia..."
fine
# Uscita:
# Esecuzione dell'operazione...
# Impossibile dividere per zero!
# Pulizia...

Il riprovare Parola chiave

Il riprovare consente di riprovare l'operazione inizio dopo che è stata catturata un'eccezione. Questo è utile per scenari come la ripetizione di richieste di rete fallite.

Esempio:

rubino
tentativi = 0
iniziare
  tentativi += 1
  puts "Tentativo #{tentativi}"
  raise "Connessione fallita"
salvataggio
  riprova se tentativi < 3
  mette "Rinuncia dopo #{tentativi} tentativi".
fine
Uscita #:
# Tentativo 1
# Tentativo 2
# Tentativo 3
# Rinuncia dopo 3 tentativi

Usare con cautela i tentativi per evitare loop infiniti.

Migliori pratiche per la gestione delle eccezioni

  1. Eccezioni specifiche per il soccorso: Evitare la nudità soccorso perché catturano tutte le clausole Errore standard e può nascondere errori imprevisti. Specificate le eccezioni esatte che vi aspettate.
    rubino
    # Cattivo
    iniziare
      Codice #
    salvataggio
      # Cattura tutto
    fine
    
    # Buono
    iniziare
      # Codice
    salvare ArgumentError, TypeError
      # Gestire errori specifici
    fine
  2. Mantenere i blocchi di salvataggio piccoli: Avvolgere solo il codice che potrebbe sollevare un'eccezione. Questo migliora la leggibilità ed evita di catturare errori non correlati.
  3. Fornire messaggi di errore significativi: Quando si sollevano delle eccezioni, includere messaggi chiari e perseguibili per facilitare il debugging.
  4. Utilizzare le eccezioni personalizzate per la logica di dominio: Creare classi di eccezioni personalizzate per errori specifici dell'applicazione, per rendere il codice più espressivo e manutenibile.
  5. Evitare l'uso eccessivo di eccezioni per il controllo del flusso: Le eccezioni servono per casi eccezionali, non per controllare il flusso del programma. Usare i condizionali per gli scenari previsti.
    rubino
    # Cattivo
    iniziare
    valore = hash[:key]
    salvataggio
    valore = nil
    fine
    
    # Buono
    valore = hash[:key] || nil
  6. Risorse per la pulizia con garantire: Utilizzo garantire per chiudere file, connessioni al database o altre risorse, anche se si verifica un'eccezione.

Esempi del mondo reale

Gestione dei file

La lettura di un file può sollevare eccezioni come Errno::ENOENT (file non trovato) o Errno::EACCES (permesso negato). Ecco come gestirli:

rubino
iniziare
  File.open("inesistente.txt", "r") do |file|
    mette file.read
  fine
salvare Errno::ENOENT
  puts "File non trovato!"
rescue Errno::EACCES
  mette "Autorizzazione negata!"
assicura
  mette "Operazione file completata".
fine
# Output: File non trovato!
# Operazione file completata.

Chiamate API

Quando si effettuano richieste HTTP, è possibile che si verifichino errori di rete o risposte non valide. Utilizzando l'opzione httparty gemma:

rubino
richiedere 'httparty'

iniziare
  risposta = HTTParty.get('https://api.example.com/data')
rescue HTTParty::Error => e
  mette "Richiesta API fallita: #{e.message}".
salvataggio SocketError
  puts "Errore di rete: Impossibile connettersi al server"
else
  mette "Risposta ricevuta: #{risposta.body}".
fine

Gestione personalizzata delle eccezioni in una classe

Ecco un esempio di classe che elabora pagamenti e utilizza eccezioni personalizzate:

rubino
classe PaymentError < StandardError; fine
classe InsufficientFundsError < PaymentError; fine
classe InvalidCardError  card.balance
    card.balance -= importo
    puts "Il pagamento di #{importo} è stato elaborato con successo".
  fine

  privato
  def valid_card?(card)
    card.number.length == 16
  fine
fine

classe Carta
  attr_accessor :number, :balance
  def initialize(numero, saldo)
    @numero = numero
    @bilancio = bilancio
  fine
fine

carta = Card.new("1234567890123456", 50)
processore = PaymentProcessor.new

iniziare
  processor.process_payment(100, carta)
salvataggio InsufficientFundsError => e
  mette "Errore: #{e.message}".
rescue InvalidCardError => e
  puts "Errore: #{e.message}"
fine
Uscita #: Errore: Fondi insufficienti

Gestione avanzata delle eccezioni

Soccorsi annidati

È possibile annidare inizio/soccorso per gestire le eccezioni a diversi livelli:

rubino
iniziare
  iniziare
    sollevare "Errore interno"
  salvataggio
    mette "Errore interno rilevato"
    sollevare "Errore esterno"
  fine
salvataggio
  mette "Errore esterno rilevato"
fine
# Uscita:
# Errore interno rilevato
# Errore esterno rilevato

Gerarchia delle eccezioni

La comprensione della gerarchia delle eccezioni di Ruby è fondamentale. Le classi chiave includono:

  • EccezioneM: Classe radice per tutte le eccezioni.
  • Errore standard: Predefinito per soccorso senza una classe; la maggior parte delle eccezioni incorporate ereditano da essa.
  • Errore di runtime: Predefinito per aumento senza classe.
  • NoMethodError, ArgumentError, TypeErrorecc.: tipi di errore specifici.

Per catturare tutte le eccezioni (comprese quelle nonErrore standard come Uscita dal sistema), utilizzare salvataggio Eccezione:

rubino
iniziare
  uscire
salvataggio dell'eccezione
  mette "Uscita catturata"
fine
Uscita #: Uscita catturata

Utilizzando salvataggio_da in Rails

In Ruby on Rails, si può usare salvataggio_da nei controllori per gestire le eccezioni a livello globale:

rubino
classe ApplicationController < ActionController::Base
  rescue_from ActiveRecord::RecordNotFound, with: :not_found

  privato

  def not_found
    renderà il file: 'public/404.html', status: :not_found
  fine
fine

Questo approccio centralizza la gestione delle eccezioni per controllori specifici.

Le insidie più comuni da evitare

  1. Catturare tutte le eccezioni alla cieca: Utilizzo soccorso senza specificare una classe di eccezione può nascondere dei bug.
  2. Uso eccessivo riprovare: Riprovare all'infinito può portare a loop infiniti o a mascherare problemi di fondo.
  3. Ignorare i dettagli delle eccezioni: Ispezionare sempre l'oggetto eccezione (e.message, e.backtrace) per il debug.
  4. Sollevamento di errori non standard: Evitare di sollevare eccezioni che non ereditano da Errore standardpoiché non saranno catturati per impostazione predefinita. soccorso clausole.
  5. Non pulire le risorse: Dimenticare di usare garantire possono lasciare file o connessioni aperte.

Conclusione

Sollevare e salvare eccezioni in Ruby è un modo potente per gestire gli errori e costruire applicazioni robuste. A RailsCarma, un'azienda leader Società di sviluppo Ruby on Railse sfruttiamo queste tecniche per creare soluzioni affidabili e manutenibili. Utilizzando aumento per segnalare gli errori, soccorso per catturarli e strumenti come riprovare, altrimenti, E garantireGli sviluppatori possono gestire gli errori in modo efficace. Le classi di eccezioni personalizzate e le clausole di salvataggio specifiche aggiungono chiarezza e precisione al codice. Seguire le migliori pratiche, come il salvataggio di eccezioni specifiche, la riduzione delle dimensioni dei blocchi di salvataggio e l'uso di messaggi di errore significativi, garantisce un codice manutenibile e affidabile.

Che si tratti di operazioni su file, chiamate API o logica specifica del dominio, il sistema di gestione delle eccezioni di Ruby offre la flessibilità necessaria per affrontare gli errori con grazia. Padroneggiando queste tecniche ed evitando le insidie più comuni, RailsCarma aiuta le aziende a costruire applicazioni Ruby resilienti che gestiscono gli errori con sicurezza.

Articoli correlati

Informazioni sull'autore del post

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *


it_ITItalian