2016-07-13 12 views
3

私は、ユーザー入力を受け取り、正常な出力値またはエラーを返す関数を持っている共通パターンを実行しています。しかし、さまざまなタイプのエラーを返すことができます。その中には、ユーザー入力の悪さや内部エラーの結果であるもの(DBが利用できないなど)があります。Golangのユーザーエラーと内部エラーを明確に区別するにはどうすればよいですか?

私の機能は次のようになり、署名があります。エラーが発生しなかった場合は、最初の戻り値は(nilでない)意味のある

// ProcessInput takes a user-input string and returns a processed value 
func ProcessInput(input string) (ProcessedValue, error, error) {} 

をユーザー入力が検証に失敗した場合、第2の戻り値がエラーです、予期しない内部エラーが発生した場合は3番目の戻り値はエラーとなります。

これはうまくいきますが、きれいに感じることはありません。さまざまなエラーが何であるかを署名から見ても分かりません。私はエラーを返す名前を考えたが、私はリターンパラメータの名前を付ける副作用が気に入らない。

クリーナーとして適用できるパターンは他にありますか? 1つのエラーが返され、呼び出し側でタイプ別に区別する必要がありますか?

答えて

7

複数の返信errorは私にはあまり気にしないようです。

なぜユーザーを表示するのに適したメッセージを返すメソッドを定義するUserErrorというインターフェイスがないのはなぜですか。返されたエラーにUserErrorが実装されていない場合は、標準の「内部サーバーエラー」メッセージを表示します。例:

type UserError interface { 
    error 
    UserError() string 
} 

type emptyInput struct {} 

func (e emptyInput) Error() string { 
    return e.UserError() 
}  

func (emptyInput) UserError() string { 
    return "Empty input" 
} 

func ProcessInput(input string) (*ProcessedValue, error) { 
    if input == "" { 
     return nil, &emptyInput{} 
    } 
} 

func httpHandler() { 
    val, err := ProcessInput(input) 
    if err != nil { 
     if userErr := err.(UserError); userErr != nil { 
      // show userError.UserError() to user 
     } else { 
      // Log error 
      // show Internal server error message 
     } 
    } 
} 
1

私は、単一のエラーリターンを持っていると 、発信者側のタイプによって区別すべきか?

これは私がお勧めするものです。さまざまな種類のエラーに対してグローバルなエラー変数を作成できます。呼び出し元は、返されたエラーの種類を確認することができます。

var ErrValidation = fmt.Errorf("Validation failed.") 

func ProcessInput(input string) (ProcessedValue, error) { 
    if !validate(input) { 
     return nil, ErrValidation 
    } 
    // process stuff and return 
} 

そして、発信者側:

value, err := ProcessInput(input) 
if err != nil { 
    if err == ErrValidation { 
     // Tell user validation failed 
    } else { 
     // Show internal server error message 
    } 
} 
// do things with value 
関連する問題