2015-11-02 15 views
7

Sono nuovo in golang, la mia applicazione deve restituire più errori in un ciclo, in seguito richiede di essere combinata e restituita come una singola stringa di errore. Non sono in grado di utilizzare le funzioni di stringa per combinare i messaggi di errore. Quali metodi possono essere utilizzati per combinare questi errori in un singolo errore prima di tornare?Combina più stringhe di errori

package main 

import (
    "fmt" 
    "strings" 
) 

func Servreturn() (err error) { 

    err1 = fmt.Errorf("Something else occured") 
    err2 = fmt.Errorf("Something else occured again") 

    // concatenate both the error 

    return err3 

} 
+0

Informazioni insufficienti. Cosa fa il cliente? Cosa fa il tuo server? Un esempio di output. – ZAky

risposta

6

È possibile utilizzare la funzione strings.Join() e append() per ottenere questa sezione.

example: golang playgorund

package main 

import (
    "fmt" 
    "strings" 
    "syscall" 
) 

func main() { 

    // create a slice for the errors 
    var errstrings []string 

    // first error 
    err1 := fmt.Errorf("First error:server error") 
    errstrings = append(errstrings, err1.Error()) 

    // do something 
    err2 := fmt.Errorf("Second error:%s", syscall.ENOPKG.Error()) 
    errstrings = append(errstrings, err2.Error()) 

    // do something else 
    err3 := fmt.Errorf("Third error:%s", syscall.ENOTCONN.Error()) 
    errstrings = append(errstrings, err3.Error()) 

    // combine and print all the error 
    fmt.Println(fmt.Errorf(strings.Join(errstrings, "\n"))) 


} 

Questo sarebbe uscita una singola stringa, che è possibile inviare al client.

First error:server1 
Second error:Package not installed 
Third error:Socket is not connected 

spero che questo aiuti!

9

Le funzioni di stringa non funzionano sugli errori perché l'errore è in realtà un'interfaccia che implementa la funzione Error() stringa.

È possibile utilizzare le funzioni stringa su err1.Error() e err2.Error() ma non sul riferimento "err1".

Alcuni errori sono strutture, come quelle ottenute dai driver di database.

Quindi non esiste un modo naturale per utilizzare le funzioni di stringa sugli errori poiché potrebbero non essere effettivamente sotto le stringhe.

Per quanto riguarda la combinazione di due errori:

facile, basta usare di nuovo fmt.Errorf.

fmt.Errorf("Combined error: %v %v", err1, err2) 

alternativa:

errors.New(err1.Error() + err2.Error()) 
+0

Altri modi diversi dall'usare fmt.Errorf(), perché non posso usare la funzione stringa? –

+0

Sicuro. Dipende da cosa intendi per "combinazione". La concatenazione delle stringhe viene eseguita usando l'operatore '+'.Oppure potresti memorizzarli singolarmente in una sezione, ad esempio i valori '' aggiungi() '. * Questa * domanda suggerisce che dovresti lavorare da solo attraverso un tutorial Go e ottenere un libro su di esso. – kostix

+1

@GregPetr Potenzialmente un altro modo pulito per farlo è quello di avere la propria struttura 'CombinedError' che prende un elenco di errori come un campo e implementa il metodo' Error() string' e fa quello che vuoi, sia che si concateni le stringhe o che sia . –

3

Per espandere su ciò @WillC aveva menzionato in un commento è possibile definire il proprio error tipo error è un tipo di interfaccia. Qualsiasi tipo che implementa una funzione Error() string implementa l'interfaccia error. Pertanto, è possibile creare un CollectionError che aggrega gli errori e restituisce una stringa di errore concatenata.

type ErrorCollector []error 

func (c *ErrorCollector) Collect(e error) { *c = append(*c, e) } 

func (c *ErrorCollector) Error() (err string) { 
    err = "Collected errors:\n" 
    for i, e := range *c { 
     err += fmt.Sprintf("\tError %d: %s\n", i, e.Error()) 
    } 

    return err 
} 

Questo fornisce una funzione di raccolta che aggiunge un dato error ad una fetta. Alla chiamata Error() string itera sulla slice e crea una stringa di errore concatenata.

func main() { 
    collector := new(ErrorCollector) 

    for i := 0; i < 10; i++ { 
     collector.Collect(errors.New(fmt.Sprintf("%d Error", i))) 
    } 

    fmt.Println(collector) 
} 

c'è una grande golang.org blog post andare oltre gli errori in modo più dettagliato. Un esempio completo di questo esempio è disponibile su The Go Playground.

+0

grazie, il tuo esempio è stato molto utile. Ci proverò e tornerò. –