2015-04-17 6 views
5

Dire che ho il seguente frammentoCome restituire un codice di stato 500 se c'è un IOException durante la lettura

public boolean checkListing() { 

    try { 

     // open the users.txt file 
     BufferedReader br = new BufferedReader(new FileReader("users.txt")); 

     String line = null; 
     while ((line = br.readLine()) != null) { 
      String[] values = line.split(" "); 
      // only interested for duplicate usernames 
      if (username.equals(values[0])) { 
       return true; 
      } 
     } 
     br.close(); 
     return false; 
    } catch (IOException e) { 
     e.printStackTrace(); 
     // what to do here 
    } 

} 

Come devo gestire l'errore se si verifica un'eccezione? Voglio sapere che è successo e restituire un codice 500 all'utente.

Devo lanciare ed eccezione e prenderlo nell'altra classe?

C'è un modo più elegante per ottenere un feedback su di esso?

+1

1) lanciare un'eccezione mantenendo l'eccezione iniziale come causa; 2) utilizzare l'oggetto composito '{result, code, failure reason}' per restituire.Preferisco 1) perché è allo stesso tempo elegante e utile: da qualsiasi punto di esecuzione è possibile ottenere una traccia completa del fallimento. –

+0

@SashaSalauyou Grazie per la risposta. Ho un po 'di problemi a capire però. Puoi darmi una fonte per saperne di più sulla seconda strada? – Rentonie

+0

BTW non dimenticare di chiudere 'br' nel blocco' finally', altrimenti la sequenza di errori può causare perdite di risorse. –

risposta

1

È possibile restituire un'istanza di questa classe:

public class Result { 

    private boolean errorOccurs; 
    private boolean isValid; 
    private Exception exception; 

    public Result(boolean isValid){ 
     this(isValid, false, null); 
    } 

    public Result(boolean isValid, boolean errorOccurs, Exception exception){ 
     this.isValid = isValid; 
     this.errorOccurs = errorOccurs; 
     this.exception = exception; 
    } 

    public boolean isValid(){ 
     return isValid; 
    } 

    public boolean errorOccurs(){ 
     return errorOccurs; 
    } 

    public Exception getException(){ 
     return exception; 
    } 
} 

Nel tuo caso:

public Result checkListing() { 

    try { 

     // open the users.txt file 
     BufferedReader br = new BufferedReader(new FileReader("users.txt")); 

     String line = null; 
     while ((line = br.readLine()) != null) { 
      String[] values = line.split(" "); 
      // only interested for duplicate usernames 
      if (username.equals(values[0])) { 
       return new Result(true); 
      } 
     } 
     br.close(); 
     return new Result(false); 
    } catch (IOException e) { 
     e.printStackTrace(); 
     return new Result(false, true, e); 
    } 
} 

E la forma breve della classe Risultato :)

public class Result { 
    public boolean errorOccurs; 
    public boolean isValid; 
    public Exception exception; 
} 
+0

Esattamente quello che stavo cercando. Grazie mille per la risposta on-line, signore. – Rentonie

+0

Ma ancora non si chiudono 'BufferedReader' e' FileReader' alla fine ... –

+1

Sì! Chiudi sempre tutti i lettori :) –

0

In questo caso, è possibile generare IOException da readLine o close.

Questa eccezione indica che si è verificata una situazione eccezionale, ad esempio la fonte del flusso non è più disponibile. Il tuo programma può essere ripristinato oppure rileggere la fonte o segnalare questo problema all'utente.

Sta a te decidere cosa fare, a seconda della tua logica, non c'è un modo preferito di farlo qui.

Nota che è necessario chiudere br in un blocco finally.

0

Modo migliore è quello di gettare un'eccezione wrapping:

try (FileReader fr = new FileReader("users.txt")) { 
    try (BufferedReader br = new BufferedReader(fr)) { 

     // ... do your work 

    } catch (IOException e) { 
     throw new RuntimeException(e); 
    } 
} catch (IOException e1) { 
    throw new RuntimeException(e1); 
} 

Si noti che qui sto aprendo le risorse nelle dichiarazioni try così da farle chiudere automaticamente al termine dell'esecuzione, non dipendenti dal risultato dell'esecuzione.

0

I due approcci più comuni che ho visto sono, come notato da Sasha Salauyou, un rethrow (potenzialmente avvolto) o un oggetto separato che fornisce maggiori informazioni.

Il problema fondamentale che si sta tentando di trattare qui è che si dispone di un metodo che si desidera restituire più di due valori con un tipo restituito che può esprimere solo due. Quindi devi restituire un tipo che supporti tutti i possibili valori di ritorno necessari o devi trovare percorsi di ritorno alternativi (come le eccezioni).

Nel mio codice, tenderei a favorire un rethrow qui. Scrivere un oggetto di ritorno dedicato diventa difficile da mantenere a lungo termine con IO perché ci sono così tanti modi diversi in cui le cose possono fallire. Tuttavia, vorrei divergere dal percorso suggerito (un'eccezione che mantiene l'eccezione originale come causa) semplicemente perché di solito non c'è una forte ragione per il wrapping. Basta dichiarare il metodo checkList per lanciare IOException, registrare il messaggio o lo stacktrace nel blocco catch e quindi lanciare l'eccezione originale.