Unify fallback and unimplemented API error handling
- Add a shared common error response schema and unknown error code for business-level fallbacks - Return business error payloads for router NoRoute and NoMethod fallbacks - Align the existing event list fallback response with the shared error structure - Introduce an explicit unimplemented API error type instead of relying on formatted strings - Make /api batch dispatch return per-item status 600 error entries for unimplemented modules and actions without failing the whole batch Signed-off-by: Sean Du <do4suki@gmail.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
package album
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
honokautils "honoka-chan/internal/utils"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@@ -11,7 +11,7 @@ func AlbumApi(ctx *gin.Context, action string) (res any, err error) {
|
||||
case "albumAll":
|
||||
res, err = albumAll(ctx)
|
||||
default:
|
||||
err = fmt.Errorf("unimplemented action: album: %s", action)
|
||||
err = honokautils.NewUnimplementedActionError("album", action)
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"honoka-chan/internal/constant"
|
||||
"honoka-chan/internal/handler/api/album"
|
||||
"honoka-chan/internal/handler/api/award"
|
||||
"honoka-chan/internal/handler/api/background"
|
||||
@@ -32,8 +32,10 @@ import (
|
||||
"honoka-chan/internal/middleware"
|
||||
"honoka-chan/internal/router"
|
||||
apischema "honoka-chan/internal/schema/api"
|
||||
commonschema "honoka-chan/internal/schema/common"
|
||||
"honoka-chan/internal/session"
|
||||
honokautils "honoka-chan/internal/utils"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@@ -108,9 +110,20 @@ func api(ctx *gin.Context) {
|
||||
case "user":
|
||||
result, err = user.UserApi(ctx, v.Action)
|
||||
default:
|
||||
err = fmt.Errorf("unimplemented api module: %s", v.Module)
|
||||
err = honokautils.NewUnimplementedModuleError(v.Module)
|
||||
}
|
||||
|
||||
if honokautils.IsUnimplementedError(err) {
|
||||
results = append(results, commonschema.ApiErrorResp{
|
||||
Result: commonschema.ErrorData{
|
||||
ErrorCode: constant.ErrorCodeUnknown,
|
||||
},
|
||||
Status: 600,
|
||||
CommandNum: false,
|
||||
TimeStamp: time.Now().Unix(),
|
||||
})
|
||||
continue
|
||||
}
|
||||
if ss.CheckErr(err) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package award
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
honokautils "honoka-chan/internal/utils"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@@ -11,7 +11,7 @@ func AwardApi(ctx *gin.Context, action string) (res any, err error) {
|
||||
case "awardInfo":
|
||||
res, err = awardInfo(ctx)
|
||||
default:
|
||||
err = fmt.Errorf("unimplemented action: award: %s", action)
|
||||
err = honokautils.NewUnimplementedActionError("award", action)
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package background
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
honokautils "honoka-chan/internal/utils"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@@ -11,7 +11,7 @@ func BackgroundApi(ctx *gin.Context, action string) (res any, err error) {
|
||||
case "backgroundInfo":
|
||||
res, err = backgroundInfo(ctx)
|
||||
default:
|
||||
err = fmt.Errorf("unimplemented action: background: %s", action)
|
||||
err = honokautils.NewUnimplementedActionError("background", action)
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package banner
|
||||
|
||||
import "fmt"
|
||||
import honokautils "honoka-chan/internal/utils"
|
||||
|
||||
func BannerApi(action string) (res any, err error) {
|
||||
switch action {
|
||||
case "bannerList":
|
||||
res, err = bannerList()
|
||||
default:
|
||||
err = fmt.Errorf("unimplemented action: banner: %s", action)
|
||||
err = honokautils.NewUnimplementedActionError("banner", action)
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package challenge
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
honokautils "honoka-chan/internal/utils"
|
||||
)
|
||||
|
||||
func ChallengeApi(action string) (res any, err error) {
|
||||
@@ -9,7 +9,7 @@ func ChallengeApi(action string) (res any, err error) {
|
||||
case "challengeInfo":
|
||||
res, err = challengeInfo()
|
||||
default:
|
||||
err = fmt.Errorf("unimplemented action: challenge: %s", action)
|
||||
err = honokautils.NewUnimplementedActionError("challenge", action)
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package costume
|
||||
|
||||
import "fmt"
|
||||
import honokautils "honoka-chan/internal/utils"
|
||||
|
||||
func CostumeApi(action string) (res any, err error) {
|
||||
switch action {
|
||||
case "costumeList":
|
||||
res, err = costumeList()
|
||||
default:
|
||||
err = fmt.Errorf("unimplemented action: costume: %s", action)
|
||||
err = honokautils.NewUnimplementedActionError("costume", action)
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package eventscenario
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
honokautils "honoka-chan/internal/utils"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@@ -11,7 +11,7 @@ func EventScenarioApi(ctx *gin.Context, action string) (res any, err error) {
|
||||
case "status":
|
||||
res, err = eventScenarioStatus(ctx)
|
||||
default:
|
||||
err = fmt.Errorf("unimplemented action: costume: %s", action)
|
||||
err = honokautils.NewUnimplementedActionError("eventscenario", action)
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package exchange
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
honokautils "honoka-chan/internal/utils"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@@ -11,7 +11,7 @@ func ExchangeApi(ctx *gin.Context, action string) (res any, err error) {
|
||||
case "owningPoint":
|
||||
res, err = owningPoint(ctx)
|
||||
default:
|
||||
err = fmt.Errorf("unimplemented action: exchange: %s", action)
|
||||
err = honokautils.NewUnimplementedActionError("exchange", action)
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package item
|
||||
|
||||
import "fmt"
|
||||
import honokautils "honoka-chan/internal/utils"
|
||||
|
||||
func ItemApi(action string) (res any, err error) {
|
||||
switch action {
|
||||
case "list":
|
||||
res, err = itemList()
|
||||
default:
|
||||
err = fmt.Errorf("unimplemented action: item: %s", action)
|
||||
err = honokautils.NewUnimplementedActionError("item", action)
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package live
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
honokautils "honoka-chan/internal/utils"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@@ -13,7 +13,7 @@ func LiveApi(ctx *gin.Context, action string) (res any, err error) {
|
||||
case "schedule":
|
||||
res, err = liveSchedule(ctx)
|
||||
default:
|
||||
err = fmt.Errorf("unimplemented action: live: %s", action)
|
||||
err = honokautils.NewUnimplementedActionError("live", action)
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package liveicon
|
||||
|
||||
import "fmt"
|
||||
import honokautils "honoka-chan/internal/utils"
|
||||
|
||||
func LiveIconApi(action string) (res any, err error) {
|
||||
switch action {
|
||||
case "liveiconInfo":
|
||||
res, err = liveIconInfo()
|
||||
default:
|
||||
err = fmt.Errorf("unimplemented action: liveicon: %s", action)
|
||||
err = honokautils.NewUnimplementedActionError("liveicon", action)
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package livese
|
||||
|
||||
import "fmt"
|
||||
import honokautils "honoka-chan/internal/utils"
|
||||
|
||||
func LiveSeApi(action string) (res any, err error) {
|
||||
switch action {
|
||||
case "liveseInfo":
|
||||
res, err = LiveSeInfo()
|
||||
default:
|
||||
err = fmt.Errorf("unimplemented action: livese: %s", action)
|
||||
err = honokautils.NewUnimplementedActionError("livese", action)
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package login
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
honokautils "honoka-chan/internal/utils"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@@ -13,7 +13,7 @@ func LoginApi(ctx *gin.Context, action string) (res any, err error) {
|
||||
case "topInfoOnce":
|
||||
res, err = loginTopInfoOnce(ctx)
|
||||
default:
|
||||
err = fmt.Errorf("unimplemented action: login: %s", action)
|
||||
err = honokautils.NewUnimplementedActionError("login", action)
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package marathon
|
||||
|
||||
import "fmt"
|
||||
import honokautils "honoka-chan/internal/utils"
|
||||
|
||||
func MarathonApi(action string) (res any, err error) {
|
||||
switch action {
|
||||
case "marathonInfo":
|
||||
res, err = marathonInfo()
|
||||
default:
|
||||
err = fmt.Errorf("unimplemented action: marathon: %s", action)
|
||||
err = honokautils.NewUnimplementedActionError("marathon", action)
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package multiunit
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
honokautils "honoka-chan/internal/utils"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@@ -11,7 +11,7 @@ func MultiUnitApi(ctx *gin.Context, action string) (res any, err error) {
|
||||
case "multiunitscenarioStatus":
|
||||
res, err = MultiUnitScenarioStatus(ctx)
|
||||
default:
|
||||
err = fmt.Errorf("unimplemented action: multiunit: %s", action)
|
||||
err = honokautils.NewUnimplementedActionError("multiunit", action)
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package museum
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
honokautils "honoka-chan/internal/utils"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@@ -11,7 +11,7 @@ func MuseumApi(ctx *gin.Context, action string) (res any, err error) {
|
||||
case "info":
|
||||
res, err = museumInfo(ctx)
|
||||
default:
|
||||
err = fmt.Errorf("unimplemented action: museum: %s", action)
|
||||
err = honokautils.NewUnimplementedActionError("museum", action)
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package navigation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
honokautils "honoka-chan/internal/utils"
|
||||
)
|
||||
|
||||
func NavigationApi(action string) (res any, err error) {
|
||||
@@ -9,7 +9,7 @@ func NavigationApi(action string) (res any, err error) {
|
||||
case "specialCutin":
|
||||
res, err = SpecialCutin()
|
||||
default:
|
||||
err = fmt.Errorf("unimplemented action: navigation: %s", action)
|
||||
err = honokautils.NewUnimplementedActionError("navigation", action)
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package notice
|
||||
|
||||
import "fmt"
|
||||
import honokautils "honoka-chan/internal/utils"
|
||||
|
||||
func NoticeApi(action string) (res any, err error) {
|
||||
switch action {
|
||||
case "noticeMarquee":
|
||||
res, err = noticeMarquee()
|
||||
default:
|
||||
err = fmt.Errorf("unimplemented action: notice: %s", action)
|
||||
err = honokautils.NewUnimplementedActionError("notice", action)
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package payment
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
honokautils "honoka-chan/internal/utils"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@@ -11,7 +11,7 @@ func PaymentApi(ctx *gin.Context, action string) (res any, err error) {
|
||||
case "productList":
|
||||
res, err = productList(ctx)
|
||||
default:
|
||||
err = fmt.Errorf("unimplemented action: payment: %s", action)
|
||||
err = honokautils.NewUnimplementedActionError("payment", action)
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package profile
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
honokautils "honoka-chan/internal/utils"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@@ -15,7 +15,7 @@ func ProfileApi(ctx *gin.Context, action string, targetUserID int) (res any, err
|
||||
case "profileInfo":
|
||||
res, err = profileInfo(ctx, targetUserID)
|
||||
default:
|
||||
err = fmt.Errorf("unimplemented action: profile: %s", action)
|
||||
err = honokautils.NewUnimplementedActionError("profile", action)
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package reward
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
honokautils "honoka-chan/internal/utils"
|
||||
)
|
||||
|
||||
func RewardApi(action string) (res any, err error) {
|
||||
@@ -11,7 +11,7 @@ func RewardApi(action string) (res any, err error) {
|
||||
case "rewardHistory":
|
||||
res, err = rewardHistory()
|
||||
default:
|
||||
err = fmt.Errorf("unimplemented action: reward: %s", action)
|
||||
err = honokautils.NewUnimplementedActionError("reward", action)
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package scenario
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
honokautils "honoka-chan/internal/utils"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@@ -11,7 +11,7 @@ func ScenarioApi(ctx *gin.Context, action string) (res any, err error) {
|
||||
case "scenarioStatus":
|
||||
res, err = scenarioStatus(ctx)
|
||||
default:
|
||||
err = fmt.Errorf("unimplemented action: scenario: %s", action)
|
||||
err = honokautils.NewUnimplementedActionError("scenario", action)
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package secretbox
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
honokautils "honoka-chan/internal/utils"
|
||||
)
|
||||
|
||||
func SecretBoxApi(action string) (res any, err error) {
|
||||
@@ -9,7 +9,7 @@ func SecretBoxApi(action string) (res any, err error) {
|
||||
case "all":
|
||||
res, err = all()
|
||||
default:
|
||||
err = fmt.Errorf("unimplemented action: secretbox: %s", action)
|
||||
err = honokautils.NewUnimplementedActionError("secretbox", action)
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package stamp
|
||||
|
||||
import "fmt"
|
||||
import honokautils "honoka-chan/internal/utils"
|
||||
|
||||
func StampApi(action string) (res any, err error) {
|
||||
switch action {
|
||||
case "stampInfo":
|
||||
res, err = stampInfo()
|
||||
default:
|
||||
err = fmt.Errorf("unimplemented action: stamp: %s", action)
|
||||
err = honokautils.NewUnimplementedActionError("stamp", action)
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package subscenario
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
honokautils "honoka-chan/internal/utils"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@@ -11,7 +11,7 @@ func SubscenarioApi(ctx *gin.Context, action string) (res any, err error) {
|
||||
case "subscenarioStatus":
|
||||
res, err = subscenarioStatus(ctx)
|
||||
default:
|
||||
err = fmt.Errorf("unimplemented action: subscenario: %s", action)
|
||||
err = honokautils.NewUnimplementedActionError("subscenario", action)
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package unit
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
honokautils "honoka-chan/internal/utils"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@@ -23,7 +23,7 @@ func UnitApi(ctx *gin.Context, action string) (res any, err error) {
|
||||
case "unitAll":
|
||||
res, err = unitAll(ctx)
|
||||
default:
|
||||
err = fmt.Errorf("unimplemented action: unit: %s", action)
|
||||
err = honokautils.NewUnimplementedActionError("unit", action)
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
honokautils "honoka-chan/internal/utils"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@@ -13,7 +13,7 @@ func UserApi(ctx *gin.Context, action string) (res any, err error) {
|
||||
case "userInfo":
|
||||
res, err = userInfo(ctx)
|
||||
default:
|
||||
err = fmt.Errorf("unimplemented action: user: %s", action)
|
||||
err = honokautils.NewUnimplementedActionError("user", action)
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user