Fix session cleanup on error paths

Signed-off-by: Sean Du <do4suki@gmail.com>
This commit is contained in:
2026-07-13 08:03:01 +08:00
parent cb8f587e30
commit 683645be8e
82 changed files with 164 additions and 132 deletions
@@ -16,7 +16,7 @@ const pagingAccomplishedPageSize = 10
func pagingAccomplishedList(ctx *gin.Context) { func pagingAccomplishedList(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
req := achievementschema.PagingAccomplishedListReq{} req := achievementschema.PagingAccomplishedListReq{}
err := honokautils.ParseRequestData(ctx, &req) err := honokautils.ParseRequestData(ctx, &req)
+1 -1
View File
@@ -12,7 +12,7 @@ import (
func seriesAll(ctx *gin.Context) { func seriesAll(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
var albumID []int var albumID []int
err := ss.MainEng.Table("album_series_m").Select("album_series_id").Find(&albumID) err := ss.MainEng.Table("album_series_m").Select("album_series_id").Find(&albumID)
+1 -1
View File
@@ -13,7 +13,7 @@ import (
func checkState(ctx *gin.Context) { func checkState(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
ss.Respond(announceschema.CheckStateDataResp{ ss.Respond(announceschema.CheckStateDataResp{
ResponseData: announceschema.CheckStateData{ ResponseData: announceschema.CheckStateData{
+1 -1
View File
@@ -41,7 +41,7 @@ import (
func api(ctx *gin.Context) { func api(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
apiReq := []apischema.ApiReq{} apiReq := []apischema.ApiReq{}
err := honokautils.ParseRequestData(ctx, &apiReq) err := honokautils.ParseRequestData(ctx, &apiReq)
+1 -1
View File
@@ -14,7 +14,7 @@ import (
func set(ctx *gin.Context) { func set(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
reqData := gjson.Parse(ctx.MustGet("request_data").(string)) reqData := gjson.Parse(ctx.MustGet("request_data").(string))
pref := usermodel.UserPref{ pref := usermodel.UserPref{
+1 -1
View File
@@ -14,7 +14,7 @@ import (
func set(ctx *gin.Context) { func set(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
reqData := gjson.Parse(ctx.MustGet("request_data").(string)) reqData := gjson.Parse(ctx.MustGet("request_data").(string))
pref := usermodel.UserPref{ pref := usermodel.UserPref{
+1 -1
View File
@@ -18,7 +18,7 @@ type bannerResp struct {
func list(ctx *gin.Context) { func list(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
data, err := apibanner.BannerApi("bannerList") data, err := apibanner.BannerApi("bannerList")
if ss.CheckErr(err) { if ss.CheckErr(err) {
+1 -1
View File
@@ -15,7 +15,7 @@ import (
func additional(ctx *gin.Context) { func additional(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
downloadReq := downloadschema.AdditionalReq{} downloadReq := downloadschema.AdditionalReq{}
err := honokautils.ParseRequestData(ctx, &downloadReq) err := honokautils.ParseRequestData(ctx, &downloadReq)
+1 -1
View File
@@ -16,7 +16,7 @@ import (
func batch(ctx *gin.Context) { func batch(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
downloadReq := downloadschema.BatchReq{} downloadReq := downloadschema.BatchReq{}
err := honokautils.ParseRequestData(ctx, &downloadReq) err := honokautils.ParseRequestData(ctx, &downloadReq)
+1 -1
View File
@@ -12,7 +12,7 @@ import (
func event(ctx *gin.Context) { func event(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
ss.Respond(downloadschema.EventResp{ ss.Respond(downloadschema.EventResp{
ResponseData: []any{}, ResponseData: []any{},
+1 -1
View File
@@ -16,7 +16,7 @@ import (
func getUrl(ctx *gin.Context) { func getUrl(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
downloadReq := downloadschema.UrlReq{} downloadReq := downloadschema.UrlReq{}
err := honokautils.ParseRequestData(ctx, &downloadReq) err := honokautils.ParseRequestData(ctx, &downloadReq)
+1 -1
View File
@@ -19,7 +19,7 @@ const overrideServerConfigFileName = "99_0_115.zip"
func update(ctx *gin.Context) { func update(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
downloadReq := downloadschema.UpdateReq{} downloadReq := downloadschema.UpdateReq{}
err := honokautils.ParseRequestData(ctx, &downloadReq) err := honokautils.ParseRequestData(ctx, &downloadReq)
+1 -1
View File
@@ -13,7 +13,7 @@ import (
func list(ctx *gin.Context) { func list(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
targets := []eventschema.TargetList{} targets := []eventschema.TargetList{}
for i := range 6 { for i := range 6 {
+1 -1
View File
@@ -13,7 +13,7 @@ import (
func startup(ctx *gin.Context) { func startup(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
startReq := eventscenarioschema.StartUpReq{} startReq := eventscenarioschema.StartUpReq{}
err := honokautils.ParseRequestData(ctx, &startReq) err := honokautils.ParseRequestData(ctx, &startReq)
+1 -1
View File
@@ -14,7 +14,7 @@ import (
func expel(ctx *gin.Context) { func expel(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
req := friendschema.UserIDReq{} req := friendschema.UserIDReq{}
err := honokautils.ParseRequestData(ctx, &req) err := honokautils.ParseRequestData(ctx, &req)
+1 -1
View File
@@ -33,7 +33,7 @@ type friendListRow struct {
func list(ctx *gin.Context) { func list(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
listReq := friendschema.ListReq{} listReq := friendschema.ListReq{}
err := honokautils.ParseRequestData(ctx, &listReq) err := honokautils.ParseRequestData(ctx, &listReq)
+1 -1
View File
@@ -15,7 +15,7 @@ import (
func request(ctx *gin.Context) { func request(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
req := friendschema.UserIDReq{} req := friendschema.UserIDReq{}
err := honokautils.ParseRequestData(ctx, &req) err := honokautils.ParseRequestData(ctx, &req)
+1 -1
View File
@@ -14,7 +14,7 @@ import (
func requestCancel(ctx *gin.Context) { func requestCancel(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
req := friendschema.UserIDReq{} req := friendschema.UserIDReq{}
err := honokautils.ParseRequestData(ctx, &req) err := honokautils.ParseRequestData(ctx, &req)
+1 -1
View File
@@ -15,7 +15,7 @@ import (
func response(ctx *gin.Context) { func response(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
req := friendschema.ResponseReq{} req := friendschema.ResponseReq{}
err := honokautils.ParseRequestData(ctx, &req) err := honokautils.ParseRequestData(ctx, &req)
+1 -1
View File
@@ -30,7 +30,7 @@ type friendSearchRow struct {
func search(ctx *gin.Context) { func search(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
req := friendschema.SearchReq{} req := friendschema.SearchReq{}
err := honokautils.ParseRequestData(ctx, &req) err := honokautils.ParseRequestData(ctx, &req)
+1 -1
View File
@@ -13,7 +13,7 @@ import (
func get(ctx *gin.Context) { func get(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
ss.Respond(gdprschema.GetResp{ ss.Respond(gdprschema.GetResp{
ResponseData: gdprschema.GetData{ ResponseData: gdprschema.GetData{
+1 -1
View File
@@ -10,7 +10,7 @@ import (
func active(ctx *gin.Context) { func active(ctx *gin.Context) {
ss := session.Attach(ctx) ss := session.Attach(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
ss.Respond(ghomeschema.ActiveResp{ ss.Respond(ghomeschema.ActiveResp{
Code: 0, Code: 0,
+1 -1
View File
@@ -14,7 +14,7 @@ import (
func initialize(ctx *gin.Context) { func initialize(ctx *gin.Context) {
ss := session.Attach(ctx) ss := session.Attach(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
initData := ghomeschema.InitializeData{ initData := ghomeschema.InitializeData{
BrandLogo: "http://gskd.sdo.com/ghome/ztc/logo/og/logo_xhdpi.png", BrandLogo: "http://gskd.sdo.com/ghome/ztc/logo/og/logo_xhdpi.png",
+1 -1
View File
@@ -34,7 +34,7 @@ const (
func login(ctx *gin.Context) { func login(ctx *gin.Context) {
ss := session.Attach(ctx) ss := session.Attach(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
data, err := ctx.GetRawData() data, err := ctx.GetRawData()
if ss.CheckErr(err) { if ss.CheckErr(err) {
+1 -1
View File
@@ -16,7 +16,7 @@ import (
func loginAuto(ctx *gin.Context) { func loginAuto(ctx *gin.Context) {
ss := session.Attach(ctx) ss := session.Attach(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
data, err := ctx.GetRawData() data, err := ctx.GetRawData()
if ss.CheckErr(err) { if ss.CheckErr(err) {
+1 -1
View File
@@ -12,7 +12,7 @@ import (
func reportRole(ctx *gin.Context) { func reportRole(ctx *gin.Context) {
ss := session.Attach(ctx) ss := session.Attach(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
randKey, err := ss.Get3DESRandKey() randKey, err := ss.Get3DESRandKey()
if ss.CheckErr(err) { if ss.CheckErr(err) {
+1 -1
View File
@@ -11,7 +11,7 @@ import (
func getCode(ctx *gin.Context) { func getCode(ctx *gin.Context) {
ss := session.Attach(ctx) ss := session.Attach(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
codeArray := `{"codeArray":[{"btntext":"好的","code":"-10264022","msg_from":2,"text":"","title":"短信验证码被阻止","type":1},{"btntext":"","code":"-10869623","msg_from":2,"text":"","title":"网络连接失败,无法一键登录","type":2},{"btntext":"","code":"10298300","msg_from":2,"text":"","title":"","type":3},{"btntext":"","code":"10298311","msg_from":2,"text":"","title":"","type":3},{"btntext":"","code":"10298312","msg_from":2,"text":"","title":"","type":3},{"btntext":"","code":"10298313","msg_from":2,"text":"","title":"","type":1},{"btntext":"","code":"10298321","msg_from":2,"text":"","title":"","type":3},{"btntext":"","code":"10298322","msg_from":2,"text":"","title":"","type":3}],"codeVersion":"1.0.5"}` codeArray := `{"codeArray":[{"btntext":"好的","code":"-10264022","msg_from":2,"text":"","title":"短信验证码被阻止","type":1},{"btntext":"","code":"-10869623","msg_from":2,"text":"","title":"网络连接失败,无法一键登录","type":2},{"btntext":"","code":"10298300","msg_from":2,"text":"","title":"","type":3},{"btntext":"","code":"10298311","msg_from":2,"text":"","title":"","type":3},{"btntext":"","code":"10298312","msg_from":2,"text":"","title":"","type":3},{"btntext":"","code":"10298313","msg_from":2,"text":"","title":"","type":1},{"btntext":"","code":"10298321","msg_from":2,"text":"","title":"","type":3},{"btntext":"","code":"10298322","msg_from":2,"text":"","title":"","type":3}],"codeVersion":"1.0.5"}`
getCodeData := map[string]any{} getCodeData := map[string]any{}
@@ -10,7 +10,7 @@ import (
func getProductList(ctx *gin.Context) { func getProductList(ctx *gin.Context) {
ss := session.Attach(ctx) ss := session.Attach(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
getProductListData := ghomeschema.GetProductListData{ getProductListData := ghomeschema.GetProductListData{
Message: []string{}, Message: []string{},
+1 -1
View File
@@ -18,7 +18,7 @@ import (
func handshake(ctx *gin.Context) { func handshake(ctx *gin.Context) {
ss := session.Attach(ctx) ss := session.Attach(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
data, err := ctx.GetRawData() data, err := ctx.GetRawData()
if ss.CheckErr(err) { if ss.CheckErr(err) {
+1 -1
View File
@@ -10,7 +10,7 @@ import (
func loginArea(ctx *gin.Context) { func loginArea(ctx *gin.Context) {
ss := session.Attach(ctx) ss := session.Attach(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
ss.Respond(ghomeschema.LoginAreaResp{ ss.Respond(ghomeschema.LoginAreaResp{
Code: 0, Code: 0,
+1 -1
View File
@@ -14,7 +14,7 @@ import (
func publicKey(ctx *gin.Context) { func publicKey(ctx *gin.Context) {
ss := session.Attach(ctx) ss := session.Attach(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
publicKeyCode := 0 publicKeyCode := 0
publicKeyMsg := "ok" publicKeyMsg := "ok"
+1 -1
View File
@@ -10,7 +10,7 @@ import (
func status(ctx *gin.Context) { func status(ctx *gin.Context) {
ss := session.Attach(ctx) ss := session.Attach(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
ss.Respond(ghomeschema.GuestStatusResp{ ss.Respond(ghomeschema.GuestStatusResp{
Code: 0, Code: 0,
+1 -1
View File
@@ -10,7 +10,7 @@ import (
func agreement(ctx *gin.Context) { func agreement(ctx *gin.Context) {
ss := session.Attach(ctx) ss := session.Attach(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
ss.Respond(ghomeschema.AgreementResp{ ss.Respond(ghomeschema.AgreementResp{
ReturnCode: 0, ReturnCode: 0,
+1 -1
View File
@@ -10,7 +10,7 @@ import (
func appReport(ctx *gin.Context) { func appReport(ctx *gin.Context) {
ss := session.Attach(ctx) ss := session.Attach(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
ss.Respond(ghomeschema.AppReportResp{ ss.Respond(ghomeschema.AppReportResp{
Code: 0, Code: 0,
+1 -1
View File
@@ -16,7 +16,7 @@ import (
func deleteMail(ctx *gin.Context) { func deleteMail(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
req := greetschema.DeleteReq{} req := greetschema.DeleteReq{}
err := honokautils.ParseRequestData(ctx, &req) err := honokautils.ParseRequestData(ctx, &req)
+1 -1
View File
@@ -18,7 +18,7 @@ import (
func user(ctx *gin.Context) { func user(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
req := greetschema.UserReq{} req := greetschema.UserReq{}
err := honokautils.ParseRequestData(ctx, &req) err := honokautils.ParseRequestData(ctx, &req)
+1 -1
View File
@@ -13,7 +13,7 @@ import (
func execute(ctx *gin.Context) { func execute(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
weeks := map[string]int{ weeks := map[string]int{
"Monday": 1, "Monday": 1,
+1 -1
View File
@@ -13,7 +13,7 @@ import (
func continuee(ctx *gin.Context) { func continuee(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
ss.Respond(BuildContinueResp(ss)) ss.Respond(BuildContinueResp(ss))
} }
+1 -1
View File
@@ -14,7 +14,7 @@ import (
func partyList(ctx *gin.Context) { func partyList(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
partyListData, err := BuildPartyListData(ss) partyListData, err := BuildPartyListData(ss)
if ss.CheckErr(err) { if ss.CheckErr(err) {
return return
+1 -1
View File
@@ -17,7 +17,7 @@ import (
func play(ctx *gin.Context) { func play(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
playReq := liveschema.PlayReq{} playReq := liveschema.PlayReq{}
err := honokautils.ParseRequestData(ctx, &playReq) err := honokautils.ParseRequestData(ctx, &playReq)
+1 -1
View File
@@ -18,7 +18,7 @@ import (
func preciseScore(ctx *gin.Context) { func preciseScore(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
playScoreReq := liveschema.PlayScoreReq{} playScoreReq := liveschema.PlayScoreReq{}
err := honokautils.ParseRequestData(ctx, &playScoreReq) err := honokautils.ParseRequestData(ctx, &playScoreReq)
+1 -1
View File
@@ -18,7 +18,7 @@ import (
func authKey(ctx *gin.Context) { func authKey(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
reqData := gjson.Parse(ctx.MustGet("request_data").(string)) reqData := gjson.Parse(ctx.MustGet("request_data").(string))
dummyToken, err := base64.StdEncoding.DecodeString(reqData.Get("dummy_token").String()) dummyToken, err := base64.StdEncoding.DecodeString(reqData.Get("dummy_token").String())
+1 -1
View File
@@ -19,7 +19,7 @@ import (
func login(ctx *gin.Context) { func login(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
has, authKeyData, err := ss.GetAuthKey(ctx.MustGet("token").(string)) has, authKeyData, err := ss.GetAuthKey(ctx.MustGet("token").(string))
if ss.CheckErr(err) { if ss.CheckErr(err) {
@@ -14,7 +14,7 @@ import (
func scenarioStartup(ctx *gin.Context) { func scenarioStartup(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
startReq := multiunitschema.ScenarioStartUpReq{} startReq := multiunitschema.ScenarioStartUpReq{}
err := honokautils.ParseRequestData(ctx, &startReq) err := honokautils.ParseRequestData(ctx, &startReq)
+1 -1
View File
@@ -13,7 +13,7 @@ import (
func info(ctx *gin.Context) { func info(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
var contents []struct { var contents []struct {
MuseumContentsId int `xorm:"museum_contents_id"` MuseumContentsId int `xorm:"museum_contents_id"`
+1 -1
View File
@@ -15,7 +15,7 @@ import (
func friendGreeting(ctx *gin.Context) { func friendGreeting(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
req := noticeschema.GreetingNoticeReq{} req := noticeschema.GreetingNoticeReq{}
err := honokautils.ParseRequestData(ctx, &req) err := honokautils.ParseRequestData(ctx, &req)
+1 -1
View File
@@ -13,7 +13,7 @@ import (
func friendVariety(ctx *gin.Context) { func friendVariety(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
ss.Respond(noticeschema.FriendVarietyResp{ ss.Respond(noticeschema.FriendVarietyResp{
ResponseData: noticeschema.FriendVarietyData{ ResponseData: noticeschema.FriendVarietyData{
@@ -15,7 +15,7 @@ import (
func userGreetingHistory(ctx *gin.Context) { func userGreetingHistory(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
req := noticeschema.GreetingNoticeReq{} req := noticeschema.GreetingNoticeReq{}
err := honokautils.ParseRequestData(ctx, &req) err := honokautils.ParseRequestData(ctx, &req)
+1 -1
View File
@@ -14,7 +14,7 @@ import (
func productList(ctx *gin.Context) { func productList(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
prodResp := paymentschema.ProductListResp{ prodResp := paymentschema.ProductListResp{
ResponseData: paymentschema.ProductListData{ ResponseData: paymentschema.ProductListData{
+1 -1
View File
@@ -13,7 +13,7 @@ import (
func get(ctx *gin.Context) { func get(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
noticeResp := personalnoticeschema.GetResp{ noticeResp := personalnoticeschema.GetResp{
ResponseData: personalnoticeschema.GetData{ ResponseData: personalnoticeschema.GetData{
+1 -1
View File
@@ -14,7 +14,7 @@ import (
func register(ctx *gin.Context) { func register(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
req := gjson.Parse(ctx.PostForm("request_data")) req := gjson.Parse(ctx.PostForm("request_data"))
pref := usermodel.UserPref{ pref := usermodel.UserPref{
+1 -1
View File
@@ -28,7 +28,7 @@ type liveRankingRow struct {
func live(ctx *gin.Context) { func live(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
req := rankingschema.LiveReq{} req := rankingschema.LiveReq{}
err := honokautils.ParseRequestData(ctx, &req) err := honokautils.ParseRequestData(ctx, &req)
+1 -1
View File
@@ -12,7 +12,7 @@ import (
func history(ctx *gin.Context) { func history(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
ss.Respond(rewardschema.HistoryResp{ ss.Respond(rewardschema.HistoryResp{
ResponseData: rewardschema.HistoryData{ ResponseData: rewardschema.HistoryData{
+1 -1
View File
@@ -12,7 +12,7 @@ import (
func list(ctx *gin.Context) { func list(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
ss.Respond(rewardschema.ListResp{ ss.Respond(rewardschema.ListResp{
ResponseData: rewardschema.ListData{ ResponseData: rewardschema.ListData{
+1 -1
View File
@@ -13,7 +13,7 @@ import (
func sellUnit(ctx *gin.Context) { func sellUnit(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
ss.Respond(rewardschema.SellUnitResp{ ss.Respond(rewardschema.SellUnitResp{
ResponseData: commonschema.ErrorData{ ResponseData: commonschema.ErrorData{
+1 -1
View File
@@ -14,7 +14,7 @@ import (
func continuee(ctx *gin.Context) { func continuee(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
req := rliveschema.TokenReq{} req := rliveschema.TokenReq{}
err := honokautils.ParseRequestData(ctx, &req) err := honokautils.ParseRequestData(ctx, &req)
+1 -1
View File
@@ -31,7 +31,7 @@ type randomLiveCandidateRow struct {
func lot(ctx *gin.Context) { func lot(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
req := rliveschema.LotReq{} req := rliveschema.LotReq{}
err := honokautils.ParseRequestData(ctx, &req) err := honokautils.ParseRequestData(ctx, &req)
+1 -1
View File
@@ -14,7 +14,7 @@ import (
func play(ctx *gin.Context) { func play(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
req := rliveschema.PlayReq{} req := rliveschema.PlayReq{}
err := honokautils.ParseRequestData(ctx, &req) err := honokautils.ParseRequestData(ctx, &req)
+1 -1
View File
@@ -14,7 +14,7 @@ import (
func startup(ctx *gin.Context) { func startup(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
startReq := scenarioschema.StartUpReq{} startReq := scenarioschema.StartUpReq{}
err := json.Unmarshal([]byte(ctx.PostForm("request_data")), &startReq) err := json.Unmarshal([]byte(ctx.PostForm("request_data")), &startReq)
+1 -1
View File
@@ -13,7 +13,7 @@ import (
func multi(ctx *gin.Context) { func multi(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
multiReq := secretboxschema.MultiReq{} multiReq := secretboxschema.MultiReq{}
err := honokautils.ParseRequestData(ctx, &multiReq) err := honokautils.ParseRequestData(ctx, &multiReq)
+1 -1
View File
@@ -18,7 +18,7 @@ import (
func pon(ctx *gin.Context) { func pon(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
ponReq := secretboxschema.PonReq{} ponReq := secretboxschema.PonReq{}
err := honokautils.ParseRequestData(ctx, &ponReq) err := honokautils.ParseRequestData(ctx, &ponReq)
+1 -1
View File
@@ -14,7 +14,7 @@ import (
func showDetail(ctx *gin.Context) { func showDetail(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
showDetailReq := secretboxschema.ShowDetailReq{} showDetailReq := secretboxschema.ShowDetailReq{}
err := honokautils.ParseRequestData(ctx, &showDetailReq) err := honokautils.ParseRequestData(ctx, &showDetailReq)
+1 -1
View File
@@ -14,7 +14,7 @@ import (
func startup(ctx *gin.Context) { func startup(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
startReq := subscenarioschema.StartUpReq{} startReq := subscenarioschema.StartUpReq{}
err := honokautils.ParseRequestData(ctx, &startReq) err := honokautils.ParseRequestData(ctx, &startReq)
+1 -1
View File
@@ -13,7 +13,7 @@ import (
func check(ctx *gin.Context) { func check(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
ss.Respond(tosschema.CheckResp{ ss.Respond(tosschema.CheckResp{
ResponseData: tosschema.CheckData{ ResponseData: tosschema.CheckData{
+1 -1
View File
@@ -17,7 +17,7 @@ import (
func deck(ctx *gin.Context) { func deck(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
deckReq := unitschema.DeckReq{} deckReq := unitschema.DeckReq{}
err := honokautils.ParseRequestData(ctx, &deckReq) err := honokautils.ParseRequestData(ctx, &deckReq)
+1 -1
View File
@@ -14,7 +14,7 @@ import (
func deckName(ctx *gin.Context) { func deckName(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
deckReq := unitschema.DeckNameReq{} deckReq := unitschema.DeckNameReq{}
err := honokautils.ParseRequestData(ctx, &deckReq) err := honokautils.ParseRequestData(ctx, &deckReq)
+1 -1
View File
@@ -14,7 +14,7 @@ import (
func favorite(ctx *gin.Context) { func favorite(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
var req unitschema.FavoriteReq var req unitschema.FavoriteReq
err := honokautils.ParseRequestData(ctx, &req) err := honokautils.ParseRequestData(ctx, &req)
+1 -1
View File
@@ -18,7 +18,7 @@ type SetResp struct {
func favoriteAccessory(ctx *gin.Context) { func favoriteAccessory(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
fmt.Println(ctx.MustGet("request_data").(string)) fmt.Println(ctx.MustGet("request_data").(string))
@@ -13,7 +13,7 @@ import (
func removableSkillEquipment(ctx *gin.Context) { func removableSkillEquipment(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
req := unitschema.RemovableSkillEquipmentReq{} req := unitschema.RemovableSkillEquipmentReq{}
err := honokautils.ParseRequestData(ctx, &req) err := honokautils.ParseRequestData(ctx, &req)
+1 -1
View File
@@ -15,7 +15,7 @@ import (
func sale(ctx *gin.Context) { func sale(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
req := unitschema.SaleReq{} req := unitschema.SaleReq{}
err := honokautils.ParseRequestData(ctx, &req) err := honokautils.ParseRequestData(ctx, &req)
+1 -1
View File
@@ -14,7 +14,7 @@ import (
func setDisplayRank(ctx *gin.Context) { func setDisplayRank(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
var req unitschema.SetDisplayRankReq var req unitschema.SetDisplayRankReq
err := honokautils.ParseRequestData(ctx, &req) err := honokautils.ParseRequestData(ctx, &req)
+1 -1
View File
@@ -15,7 +15,7 @@ import (
func wearAccessory(ctx *gin.Context) { func wearAccessory(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
req := unitschema.WearAccessoryReq{} req := unitschema.WearAccessoryReq{}
err := honokautils.ParseRequestData(ctx, &req) err := honokautils.ParseRequestData(ctx, &req)
+1 -1
View File
@@ -15,7 +15,7 @@ import (
func changeName(ctx *gin.Context) { func changeName(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
req := gjson.Parse(ctx.MustGet("request_data").(string)) req := gjson.Parse(ctx.MustGet("request_data").(string))
var oldName string var oldName string
+1 -1
View File
@@ -14,7 +14,7 @@ import (
func changeNavi(ctx *gin.Context) { func changeNavi(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
req := gjson.Parse(ctx.MustGet("request_data").(string)) req := gjson.Parse(ctx.MustGet("request_data").(string))
pref := usermodel.UserPref{ pref := usermodel.UserPref{
@@ -12,7 +12,7 @@ import (
func setNotificationToken(ctx *gin.Context) { func setNotificationToken(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
ss.Respond(userschema.SetNotificationTokenResp{ ss.Respond(userschema.SetNotificationTokenResp{
ResponseData: []any{}, ResponseData: []any{},
+1 -1
View File
@@ -13,7 +13,7 @@ import (
func userInfo(ctx *gin.Context) { func userInfo(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.FinalizeOrRollback()
userResp := userschema.UserInfoResp{ userResp := userschema.UserInfoResp{
ResponseData: userschema.UserInfoData{ ResponseData: userschema.UserInfoData{
+8 -3
View File
@@ -29,10 +29,15 @@ func Common(ctx *gin.Context) {
ss := session.Attach(ctx) ss := session.Attach(ctx)
ctx.Set("session", ss) ctx.Set("session", ss)
defer ss.FinalizeOrRollback()
if ctx.Request.URL.Path != "/login/authkey" && ctx.Request.URL.Path != "/login/login" { if ctx.IsAborted() {
return
}
if !honokautils.IsMainLoginEndpoint(ctx.Request.URL.Path) {
if ss.UserPref.ForceRelogin { if ss.UserPref.ForceRelogin {
honokautils.AbortMaintenanceJSON(ctx, http.StatusNotFound, honokautils.NewNotFoundContent(ctx.Request.URL.String())) ss.AbortWithStatus(http.StatusNotFound, honokautils.NewNotFoundContent(ctx.Request.URL.Path))
return return
} }
} }
@@ -40,7 +45,7 @@ func Common(ctx *gin.Context) {
authorize := ctx.GetHeader("Authorize") authorize := ctx.GetHeader("Authorize")
params, err := url.ParseQuery(authorize) params, err := url.ParseQuery(authorize)
if err != nil { if err != nil {
honokautils.AbortMaintenanceJSON(ctx, http.StatusNotFound, honokautils.NewNotFoundContent(ctx.Request.URL.String())) ss.AbortWithStatus(http.StatusNotFound, honokautils.NewNotFoundContent(ctx.Request.URL.Path))
return return
} }
+7 -7
View File
@@ -21,18 +21,18 @@ func Recovery() gin.HandlerFunc {
stack := debug.Stack() stack := debug.Stack()
log.Printf("panic serving %s %s: %v\n%s", ctx.Request.Method, ctx.Request.URL.String(), recovered, stack) log.Printf("panic serving %s %s: %v\n%s", ctx.Request.Method, ctx.Request.URL.String(), recovered, stack)
if value, ok := ctx.Get("session"); ok {
if ss, ok := value.(*session.Session); ok {
ss.Rollback()
}
}
if !honokautils.IsMainPHPRequest(ctx.Request.URL.Path) { if !honokautils.IsMainPHPRequest(ctx.Request.URL.Path) {
ctx.AbortWithStatus(http.StatusInternalServerError) ctx.AbortWithStatus(http.StatusInternalServerError)
return return
} }
content := honokautils.NewPanicContent(recovered, stack) honokautils.AbortMaintenanceJSON(ctx, http.StatusInternalServerError, honokautils.NewPanicContent())
if value, ok := ctx.Get("session"); ok {
value.(*session.Session).AbortWithStatus(http.StatusInternalServerError, content)
return
}
honokautils.AbortMaintenanceJSON(ctx, http.StatusInternalServerError, content)
}() }()
ctx.Next() ctx.Next()
+1 -1
View File
@@ -116,7 +116,7 @@ func SifRouter(r *gin.Engine) {
return return
} }
honokautils.AbortMaintenanceJSON(ctx, http.StatusNotFound, honokautils.NewNotFoundContent(ctx.Request.URL.String())) honokautils.AbortMaintenanceJSON(ctx, http.StatusNotFound, honokautils.NewNotFoundContent(ctx.Request.URL.Path))
} }
r.NoRoute(notFoundHandler) r.NoRoute(notFoundHandler)
r.NoMethod(notFoundHandler) r.NoMethod(notFoundHandler)
+21 -2
View File
@@ -90,7 +90,7 @@ func (ss *Session) Finalize() {
if err := ss.UserEng.Commit(); err != nil { if err := ss.UserEng.Commit(); err != nil {
log.Println(err.Error()) log.Println(err.Error())
ss.closeAllSessions(false) ss.closeAllSessions(false)
ss.respondError(http.StatusInternalServerError, honokautils.NewInternalErrorContent(err)) ss.respondError(http.StatusInternalServerError, honokautils.NewInternalErrorContent())
return return
} }
@@ -106,7 +106,7 @@ func (ss *Session) Abort(err error) {
msg := ss.formatAbortMessage(err) msg := ss.formatAbortMessage(err)
log.Println(msg) log.Println(msg)
ss.abortWithContent(http.StatusInternalServerError, honokautils.NewErrorContent("SessionAbort", msg)) ss.abortWithContent(http.StatusInternalServerError, honokautils.NewInternalErrorContent())
} }
func (ss *Session) AbortWithStatus(status int, content any) { func (ss *Session) AbortWithStatus(status int, content any) {
@@ -116,6 +116,25 @@ func (ss *Session) AbortWithStatus(status int, content any) {
ss.abortWithContent(status, content) ss.abortWithContent(status, content)
} }
// FinalizeOrRollback commits successful requests and rolls back before a panic reaches recovery.
func (ss *Session) FinalizeOrRollback() {
defer func() {
if recovered := recover(); recovered != nil {
ss.Rollback()
panic(recovered)
}
}()
ss.Finalize()
}
func (ss *Session) Rollback() {
if ss.done {
return
}
ss.done = true
ss.closeAllSessions(true)
}
func (ss *Session) formatAbortMessage(err error) string { func (ss *Session) formatAbortMessage(err error) string {
skip := 2 skip := 2
if pc, _, _, ok := runtime.Caller(2); ok { if pc, _, _, ok := runtime.Caller(2); ok {
+12 -43
View File
@@ -4,7 +4,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"net/http" "net/http"
"reflect"
"strconv" "strconv"
"strings" "strings"
@@ -48,16 +47,19 @@ func IsUnimplementedError(err error) bool {
const maintenanceHeader = "Maintenance" const maintenanceHeader = "Maintenance"
type ErrorContent struct { type ErrorContent struct {
Detail string `json:"detail,omitempty"` Detail string `json:"detail,omitempty"`
Exception string `json:"exception,omitempty"` Exception string `json:"exception,omitempty"`
Message string `json:"message,omitempty"` Message string `json:"message,omitempty"`
Traceback []string `json:"traceback,omitempty"`
} }
func IsMainPHPRequest(path string) bool { func IsMainPHPRequest(path string) bool {
return path == "/main.php" || strings.HasPrefix(path, "/main.php/") return path == "/main.php" || strings.HasPrefix(path, "/main.php/")
} }
func IsMainLoginEndpoint(path string) bool {
return path == "/main.php/login/authkey" || path == "/main.php/login/login"
}
func WriteMaintenanceJSON(setHeader func(string, string), writeJSON func(int, any), status int, content any) { func WriteMaintenanceJSON(setHeader func(string, string), writeJSON func(int, any), status int, content any) {
setHeader("Content-Type", "application/json; charset=utf-8") setHeader("Content-Type", "application/json; charset=utf-8")
setHeader("status_code", strconv.Itoa(status)) setHeader("status_code", strconv.Itoa(status))
@@ -80,46 +82,13 @@ func NewNotFoundContent(path string) ErrorContent {
return NewDetailContent(fmt.Sprintf("Endpoint not found: %s", path)) return NewDetailContent(fmt.Sprintf("Endpoint not found: %s", path))
} }
func NewInternalErrorContent(err error) ErrorContent { func NewInternalErrorContent() ErrorContent {
return ErrorContent{ return ErrorContent{
Exception: exceptionName(err), Exception: "InternalServerError",
Message: err.Error(), Message: http.StatusText(http.StatusInternalServerError),
} }
} }
func NewErrorContent(exception, message string) ErrorContent { func NewPanicContent() ErrorContent {
return ErrorContent{ return NewInternalErrorContent()
Exception: exception,
Message: message,
}
}
func NewPanicContent(recovered any, stack []byte) ErrorContent {
return ErrorContent{
Exception: "panic",
Message: fmt.Sprint(recovered),
Traceback: splitLines(stack),
}
}
func exceptionName(err error) string {
if err == nil {
return http.StatusText(http.StatusInternalServerError)
}
typ := reflect.TypeOf(err)
if typ.Kind() == reflect.Pointer {
typ = typ.Elem()
}
if name := typ.Name(); name != "" {
return name
}
return typ.String()
}
func splitLines(stack []byte) []string {
if len(stack) == 0 {
return nil
}
return strings.Split(strings.TrimSpace(string(stack)), "\n")
} }
+39
View File
@@ -0,0 +1,39 @@
package honokautils
import (
"net/http"
"testing"
)
func TestInternalErrorContentIsSanitized(t *testing.T) {
content := NewInternalErrorContent()
if content.Exception != "InternalServerError" {
t.Fatalf("unexpected exception: %q", content.Exception)
}
if content.Message != http.StatusText(http.StatusInternalServerError) {
t.Fatalf("unexpected message: %q", content.Message)
}
}
func TestPanicContentIsSanitized(t *testing.T) {
content := NewPanicContent()
if content != NewInternalErrorContent() {
t.Fatalf("panic content exposes a distinct internal detail: %#v", content)
}
}
func TestIsMainLoginEndpoint(t *testing.T) {
for _, path := range []string{"/main.php/login/authkey", "/main.php/login/login"} {
if !IsMainLoginEndpoint(path) {
t.Fatalf("expected %q to be a main.php login endpoint", path)
}
}
for _, path := range []string{"/login/authkey", "/main.php/user/userInfo"} {
if IsMainLoginEndpoint(path) {
t.Fatalf("expected %q not to be a main.php login endpoint", path)
}
}
}