2016-12-31 4 views
1

エラーの配列(エラーの種類)がありますが、JSON形式でクライアントを返そうとすると空になります。エラーの配列をGoのJSONに変換する方法

それは、このように作成された

:私のコントローラで

var (
    ErrEmptyName = errors.New("Nome não pode ser vázio") 
    ErrInvalidType = errors.New("Tipo de pessoa inválido") 
) 

func (p Person) Validate() []error { 

    var errors []error 

    if govalidator.IsNull(p.Name) { 
     errors = append(errors, ErrEmptyName) 
    } 

    if p.Type != "F" && p.Type != "J" { 
     errors = append(errors, ErrInvalidType) 
    } 

    return errors 
) 

を:

err := person.Validate() 
c.JSON(422, gin.H{"errors" : err}) 

マイ出力:

{"errors":"[{}]"} 

答えて

1

error typeは、エラーメッセージを文字列として返すError()メソッドを実装する必要のあるインターフェイスです。これはここに定義されています:https://golang.org/pkg/builtin/#errorerrorタイプがインターフェイスである理由は、より詳細な情報を取得するために型キャストできるタイプをerrorに許可することです。

fmt.Printlnlog.Printlnのような機能は、Error()からのメッセージを表示するように自動的にerrorタイプを解決しますが、JSONライブラリはそうではありません。この問題を回避する最も簡単な方法は、[]errorのエラーメッセージを[]stringに変換し、それをエンコードすることです。

forループでこれを行うコード例を次に示します。

errs := person.Validate() 
strErrors := make([]string, len(errs)) 

for i, err := range errs { 
    strErrors[i] = err.Error() 
} 

c.JSON(422, gin.H{"errors" : strErrors}) 
0

errorタイプは、単一Error()方法とのインタフェースであり、それはjsonパッケージ(Error()メソッドがその上に呼び出されていない)に特別ではありません。

ただし、errorの値には、整列可能な静的型の値が格納されている場合があり、json.Marshalerを実装することによって独自の整列ロジックを定義できます。単にerrorError()メソッドを呼び出すことによってstringに変換するということは、カスタムマーシャリングロジックを尊重していないことを意味します。

だから私たちはあるべき私たちのマーシャリング・ロジックを実装することができた上で、私たち自身のエラースライスタイプを作成することをお勧め:

  • チェックエラー値は、json.Marshalerを実装し、もしそうなら、それは自分自身を整列させた場合簡単にマーシャリングすることができますstring「を得る」ためのフォールバックケース呼び出しerror.Error()など他

これはそれのように見える可能性がどのようにされています

type JSONErrs []error 

func (je JSONErrs) MarshalJSON() ([]byte, error) { 
    res := make([]interface{}, len(je)) 
    for i, e := range je { 
     if _, ok := e.(json.Marshaler); ok { 
      res[i] = e // e knows how to marshal itself 
     } else { 
      res[i] = e.Error() // Fallback to the error string 
     } 
    } 
    return json.Marshal(res) 
} 

そして、これはあなたがそれを使用する方法である。

err := person.Validate() 
c.JSON(422, gin.H{"errors" : JSONErrs(err)}) 

は、私たちのJSONErrsをテストしてみましょう。

type MyErr struct{ line int } 

func (me MyErr) Error() string { return "Invalid input!" } 

func (me MyErr) MarshalJSON() ([]byte, error) { 
    return json.Marshal(
     struct { 
      Type, Error string 
      AtLine  int 
     }{"MyErr", me.Error(), me.line}) 
} 

とテストコード:

errs := []error{ 
    errors.New("first"), 
    errors.New("second"), 
    MyErr{16}, 
} 

data, err := json.Marshal(JSONErrs(errs)) 
fmt.Println(string(data), err) 

出力(Go Playground上でそれを試してみてください):

["first","second",{"Type":"MyErr","Error":"Invalid input!","AtLine":16}] <nil> 
我々はまた、カスタムマーシャリング・ロジックを実装するカスタム・エラー・タイプを使用しています
関連する問題