traPtitech / knoQ

進捗部屋・イベント管理システム
8 stars 2 forks source link

Fix/issue504 #556

Closed iChemy closed 2 months ago

iChemy commented 3 months ago

close #504

iChemy commented 3 months ago

本番環境でも確認

{"time":"2024-07-15T11:51:37.312581325Z","level":"-","prefix":"echo","file":"recover.go","line":"119","message":"[PANIC RECOVER] runtime error: invalid memory address or nil pointer dereference goroutine 143756 [running]:\ngithub.com/traPtitech/knoQ/router.(*Handlers).SetupRoute.Recover.RecoverWithConfig.func4.1.1()\n\t/go/pkg/mod/github.com/labstack/echo/v4@v4.12.0/middleware/recover.go:99 +0x165\npanic({0xa24d40?, 0xf8d780?})\n\t/usr/local/go/src/runtime/panic.go:770 +0x132\ngithub.com/traPtitech/knoQ/infra/db.(*dialector).SavePoint(0xf91d80?, 0xa9fae0?, {0xc0014e91c0?, 0xa?})\n\t<autogenerated>:1 +0x24\ngorm.io/gorm.(*DB).SavePoint(0xc006ef6120, {0xc0014e91c0, 0xa})\n\t/go/pkg/mod/gorm.io/gorm@v1.25.10/finisher_api.go:724 +0xda\ngorm.io/gorm.(*DB).Transaction(0xc006ef6120, 0xc0013ed2f0, {0x0?, 0x0?, 0x0?})\n\t/go/pkg/mod/gorm.io/gorm@v1.25.10/finisher_api.go:626 +0xea\ngithub.com/traPtitech/knoQ/infra/db.saveUser(0xc006ef6120, 0xc0013ab080)\n\t/app/infra/db/user.go:75 +0xa5\ngithub.com/traPtitech/knoQ/infra/db.(*GormRepository).SyncUsers.func1(0xc006ef6120)\n\t/app/infra/db/user.go:49 +0xa6\ngorm.io/gorm.(*DB).Transaction(0xc000250ab0, 0xc00104c020, {0x0?, 0x0?, 0x0?})\n\t/go/pkg/mod/gorm.io/gorm@v1.25.10/finisher_api.go:651 +0x25e\ngithub.com/traPtitech/knoQ/infra/db.(*GormRepository).SyncUsers(0xc0002bb9e0, {0xc000ca3008, 0x71f, 0x8ff})\n\t/app/infra/db/user.go:35 +0x8b\ngithub.com/traPtitech/knoQ/repository.(*Repository).SyncUsers(0xc0002bb9e0, 0xc00024f860?)\n\t/app/repository/user.go:44 +0x292\ngithub.com/traPtitech/knoQ/router.(*Handlers).HandleSyncUser(0xc000248ea0, {0xbc6c40, 0xc00024f860})\n\t/app/router/users.go:70 +0x43\ngithub.com/traPtitech/knoQ/router.(*Handlers).PrivilegeUserMiddleware-fm.(*Handlers).PrivilegeUserMiddleware.func1({0xbc6c40, 0xc00024f860})\n\t/app/router/middleware.go:117 +0x66\ngithub.com/traPtitech/knoQ/router.(*Handlers).TraQUserMiddleware-fm.(*Handlers).TraQUserMiddleware.func1({0xbc6c40, 0xc00024f860})\n\t/app/router/middleware.go:101 +0x142\ngithub.com/labstack/echo/v4.(*Echo).add.func1({0xbc6c40, 0xc00024f860})\n\t/go/pkg/mod/github.com/labstack/echo/v4@v4.12.0/echo.go:587 +0x4b\ngithub.com/labstack/echo/v4/middleware.StaticWithConfig.func1.1({0xbc6c40, 0xc00024f860})\n\t/go/pkg/mod/github.com/labstack/echo/v4@v4.12.0/middleware/static.go:166 +0x95b\ngithub.com/labstack/echo/v4/middleware.CORSWithConfig.func1.1({0xbc6c40, 0xc00024f860})\n\t/go/pkg/mod/github.com/labstack/echo/v4@v4.12.0/middleware/cors.go:253 +0x562\ngithub.com/traPtitech/knoQ/router.(*Handlers).SetupRoute.ServerVersionMiddleware.func3.1({0xbc6c40, 0xc00024f860})\n\t/app/router/middleware.go:78 +0x79\ngithub.com/traPtitech/knoQ/router.(*Handlers).SetupRoute.Middleware.MiddlewareWithConfig.func6.1({0xbc6c40, 0xc00024f860})\n\t/go/pkg/mod/github.com/labstack/echo-contrib@v0.17.1/session/session.go:73 +0x104\ngithub.com/traPtitech/knoQ/router.(*Handlers).SetupRoute.AccessLoggingMiddleware.func2.1({0xbc6c40, 0xc00024f860})\n\t/app/router/middleware.go:26 +0x7c\ngithub.com/traPtitech/knoQ/router.(*Handlers).SetupRoute.Secure.SecureWithConfig.func5.1({0xbc6c40, 0xc00024f860})\n\t/go/pkg/mod/github.com/labstack/echo/v4@v4.12.0/middleware/secure.go:141 +0x364\ngithub.com/traPtitech/knoQ/router.(*Handlers).SetupRoute.Recover.RecoverWithConfig.func4.1({0xbc6c40, 0xc00024f860})\n\t/go/pkg/mod/github.com/labstack/echo/v4@v4.12.0/middleware/recover.go:130 +0x114\ngithub.com/labstack/echo/v4.(*Echo).ServeHTTP(0xc0001806c8, {0xbbdde0, 0xc000118000}, 0xc0003979e0)\n\t/go/pkg/mod/github.com/labstack/echo/v4@v4.12.0/echo.go:674 +0x327\nnet/http.serverHandler.ServeHTTP({0xc006ef65a0?}, {0xbbdde0?, 0xc000118000?}, 0x6?)\n\t/usr/local/go/src/net/http/server.go:3142 +0x8e\nnet/http.(*conn).serve(0xc0000f5200, {0xbbecf8, 0xc000074480})\n\t/usr/local/go/src/net/http/server.go:2044 +0x5e8\ncreated by net/http.(*Server).Serve in goroutine 28\n\t/usr/local/go/src/net/http/server.go:3290 +0x4b4\n\ngoroutine 1 [chan receive, 7878 minutes]:\nmain.main()\n\t/app/main.go:125 +0x8cb\n\ngoroutine 21 [select, 9 minutes]:\ngithub.com/patrickmn/go-cache.(*janitor).Run(0xc0001d5c50, 0xc000215180)\n\t/go/pkg/mod/github.com/patrickmn/go-cache@v2.1.0+incompatible/cache.go:1079 +0x7d\ncreated by github.com/patrickmn/go-cache.runJanitor in goroutine 1\n\t/go/pkg/mod/github.com/patrickmn/go-cache@v2.1.0+incompatible/cache.go:1099 +0x\n"}
iChemy commented 3 months ago

mysql.New() で返される値は gorm.Dialector, gorm.Translator, gorm.SavePointerDialectorInterface を全て実装している

現在の実装だと dialectorgorm.SavePointerDialectorInterface を実装しているはずということになっている (そのためキャストはできる) が dgorm.SavePointerDialectorInterface として働く実体を持っていないため null ポインタへのアクセスが発生する.

dialector に実態を持たせるように実装する方法もある (gorm.Translator のようにオーバーライドさせることである) ただし,それならそもそも mysql.New() で返されるものがこれら全てを実装しているのだからそれを使えば良いはず.

また,dialector 型を定義するメリットはそれが gorm.Dialector, gorm.SavePointerDialectorInterface を実装していることを確定させることであるが gorm.Dialector, gorm.SavePointerDialectorInterface の実装が確定していることで成り立っている部分はないためそもそもdialector 型を利用する意味はない

iChemy commented 3 months ago

mysql.New が返すのは mysql.Dialector 構造体.これを明示的に gorm.Dialector インターフェースとして扱ってしまうと,多分gorm.Dialector インターフェースが持っているメソッド以外は使えないものとして扱われる(はず,)

Nzt3-gh commented 2 months ago

(私がprivilegeではなかったのでIsPrivilegeをいじってのローカルでのテストですが) /api/users/sync で500エラーが出ていたのが201になったことがこちらでも確認できました。

Nzt3-gh commented 2 months ago

mysql.New()が返すのはgorm.Dialectorではないですか? GORM MySQL Driverのやつ

iChemy commented 2 months ago

関数の宣言としてはgorm.Dialector(インターフェース) を返していますね. 関数の実装を見ると (gorm.Dialectorインターフェースを実装している)mysql.Dialector 構造体を返していますね.

で,この mysql.Dialector 構造体は gorm.Translatorインターフェースとgorm.SavePointerDialectorInterfaceインターフェース実装しているという感じです