Gin: 中止vsパニック

作成日 2015年06月14日  ·  3コメント  ·  ソース: gin-gonic/gin

エラーを返したいときは、次のコードを書く必要があります

if err != nil {
    c.AbortWithError(code, err)
    return
}

returnたくさんあるのは醜いです

パニックを使用することがおそらくベストプラクティスだと思います。 Javaのthrow Exception

if err != nil {
    panic(err) // maybe err is ErrUserNotFound
}

エラーは次のように定義されます

type HTTPError interface {
    HTTPStatus() int
}

catchErrorミドルウェアを使用してエラーをキャッチし、 HTTPStatus中止します

func catchError() gin.HandlerFunc {
    return func(c *gin.Context) {
        defer func() {
            if err := recover(); err != nil {
                switch err.(type) {
                case HTTPError:
                    e := err.(*errors.Error)
                    c.JSON(e.HTTPStatus(), e)
                    c.Abort()
                default:
                    c.AbortWithStatus(http.StatusInternalServerError)
                }
            }
        }()
        c.Next()
    }
}

醜いreturn多くが削除されます

bug wontfix

最も参考になるコメント

ヒント:コードをより小さな関数にリファクタリングするので、繰り返す代わりに:

if err != nil {
    c.AbortWithStatus(code, error)
    return 
}

あなたがやる:

func dosomething() error {
    err = dosomething1()
    if err != nil {
        return err
    }
    err = dosomething2()
    if err != nil {
        return err
    }
    err = dosomething3()
    if err != nil {
        return err
    }
}

func handler(c *gin.Context) {
    err := dosomething()
    if err != nil {
        c.AbortWithStatus(400, err)
        return;
    }
    // ...
}

全てのコメント3件

@lileeの現在のベストプラクティスは、次のことです。

AbortWithError()
return;

次に、ミドルウェアはエラーを処理するためにc.Errorsを読み取ります。

panic()を使用することは悪い考えです:

  • Goの慣用句ではありません。 Goでは、panic()は厳密な例外(またはアサーション)です。 つまり、本当に悪いこと(おそらくバグ)が発生しました。
  • panic()の呼び出しが遅い
  • panic()が呼び出されると、panic()は通常500を意味するため、ほとんどのミドルウェアは正しく機能しません。
  • デバッグ:実際のクラッシュ(access no nilなど)とエラーを区別することはできません。

もちろん、好きなものを自由に使用できますが、panic()を使用してロジックの通常のフローを制御することは、Goのアンチパターンです。

ヒント:コードをより小さな関数にリファクタリングするので、繰り返す代わりに:

if err != nil {
    c.AbortWithStatus(code, error)
    return 
}

あなたがやる:

func dosomething() error {
    err = dosomething1()
    if err != nil {
        return err
    }
    err = dosomething2()
    if err != nil {
        return err
    }
    err = dosomething3()
    if err != nil {
        return err
    }
}

func handler(c *gin.Context) {
    err := dosomething()
    if err != nil {
        c.AbortWithStatus(400, err)
        return;
    }
    // ...
}

説明ありがとうございます

このページは役に立ちましたか?
0 / 5 - 0 評価