Skip to content

Commit 94d765d

Browse files
committed
Merge remote-tracking branch 'giteaofficial/main'
* giteaofficial/main: [skip ci] Updated translations via Crowdin Fix edithook api can not update package, status and workflow_job events (go-gitea#34495) Fix url validation in webhook add/edit API (go-gitea#34492) Add R-HNF to the TRANSLATORS file (go-gitea#34494) Add missing setting load in dump-repo command (go-gitea#34479) nix flake update (go-gitea#34476) Fix get / delete runner to use consistent http 404 and 500 status (go-gitea#34480) Change "rejected" to "changes requested" in 3rd party PR review notification (go-gitea#34481) Add migrations tests (go-gitea#34456) Fix project board view (go-gitea#34470)
2 parents 69535a9 + ec10c6b commit 94d765d

File tree

15 files changed

+305
-96
lines changed

15 files changed

+305
-96
lines changed

cmd/dump_repo.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ wiki, issues, labels, releases, release_assets, milestones, pull_requests, comme
8080
}
8181

8282
func runDumpRepository(ctx *cli.Context) error {
83+
setupConsoleLogger(log.INFO, log.CanColorStderr, os.Stderr)
84+
85+
setting.DisableLoggerInit()
86+
setting.LoadSettings() // cannot access skip_tls_verify settings otherwise
87+
8388
stdCtx, cancel := installSignals()
8489
defer cancel()
8590

flake.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

models/migrations/v1_23/v302.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,8 @@ func AddIndexToActionTaskStoppedLogExpired(x *xorm.Engine) error {
1414
Stopped timeutil.TimeStamp `xorm:"index(stopped_log_expired)"`
1515
LogExpired bool `xorm:"index(stopped_log_expired)"`
1616
}
17-
return x.Sync(new(ActionTask))
17+
_, err := x.SyncWithOptions(xorm.SyncOptions{
18+
IgnoreDropIndices: true,
19+
}, new(ActionTask))
20+
return err
1821
}

models/migrations/v1_23/v302_test.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Copyright 2025 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package v1_23 //nolint
5+
6+
import (
7+
"testing"
8+
9+
"code.gitea.io/gitea/models/migrations/base"
10+
"code.gitea.io/gitea/modules/timeutil"
11+
12+
"github.com/stretchr/testify/assert"
13+
)
14+
15+
func Test_AddIndexToActionTaskStoppedLogExpired(t *testing.T) {
16+
type ActionTask struct {
17+
ID int64
18+
JobID int64
19+
Attempt int64
20+
RunnerID int64 `xorm:"index"`
21+
Status int `xorm:"index"`
22+
Started timeutil.TimeStamp `xorm:"index"`
23+
Stopped timeutil.TimeStamp `xorm:"index(stopped_log_expired)"`
24+
25+
RepoID int64 `xorm:"index"`
26+
OwnerID int64 `xorm:"index"`
27+
CommitSHA string `xorm:"index"`
28+
IsForkPullRequest bool
29+
30+
Token string `xorm:"-"`
31+
TokenHash string `xorm:"UNIQUE"` // sha256 of token
32+
TokenSalt string
33+
TokenLastEight string `xorm:"index token_last_eight"`
34+
35+
LogFilename string // file name of log
36+
LogInStorage bool // read log from database or from storage
37+
LogLength int64 // lines count
38+
LogSize int64 // blob size
39+
LogIndexes []int64 `xorm:"LONGBLOB"` // line number to offset
40+
LogExpired bool `xorm:"index(stopped_log_expired)"` // files that are too old will be deleted
41+
42+
Created timeutil.TimeStamp `xorm:"created"`
43+
Updated timeutil.TimeStamp `xorm:"updated index"`
44+
}
45+
46+
// Prepare and load the testing database
47+
x, deferable := base.PrepareTestEnv(t, 0, new(ActionTask))
48+
defer deferable()
49+
50+
assert.NoError(t, AddIndexToActionTaskStoppedLogExpired(x))
51+
}

models/migrations/v1_23/v304.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,8 @@ func AddIndexForReleaseSha1(x *xorm.Engine) error {
99
type Release struct {
1010
Sha1 string `xorm:"INDEX VARCHAR(64)"`
1111
}
12-
return x.Sync(new(Release))
12+
_, err := x.SyncWithOptions(xorm.SyncOptions{
13+
IgnoreDropIndices: true,
14+
}, new(Release))
15+
return err
1316
}

models/migrations/v1_23/v304_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Copyright 2025 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package v1_23 //nolint
5+
6+
import (
7+
"testing"
8+
9+
"code.gitea.io/gitea/models/migrations/base"
10+
"code.gitea.io/gitea/modules/timeutil"
11+
12+
"github.com/stretchr/testify/assert"
13+
)
14+
15+
func Test_AddIndexForReleaseSha1(t *testing.T) {
16+
type Release struct {
17+
ID int64 `xorm:"pk autoincr"`
18+
RepoID int64 `xorm:"INDEX UNIQUE(n)"`
19+
PublisherID int64 `xorm:"INDEX"`
20+
TagName string `xorm:"INDEX UNIQUE(n)"`
21+
OriginalAuthor string
22+
OriginalAuthorID int64 `xorm:"index"`
23+
LowerTagName string
24+
Target string
25+
Title string
26+
Sha1 string `xorm:"VARCHAR(64)"`
27+
NumCommits int64
28+
Note string `xorm:"TEXT"`
29+
IsDraft bool `xorm:"NOT NULL DEFAULT false"`
30+
IsPrerelease bool `xorm:"NOT NULL DEFAULT false"`
31+
IsTag bool `xorm:"NOT NULL DEFAULT false"` // will be true only if the record is a tag and has no related releases
32+
CreatedUnix timeutil.TimeStamp `xorm:"INDEX"`
33+
}
34+
35+
// Prepare and load the testing database
36+
x, deferable := base.PrepareTestEnv(t, 0, new(Release))
37+
defer deferable()
38+
39+
assert.NoError(t, AddIndexForReleaseSha1(x))
40+
}

options/locale/TRANSLATORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ Piotr Orzechowski <piotr AT orzechowski DOT tech>
6666
Richard Bukovansky <richard DOT bukovansky AT gmail DOT com>
6767
Robert Nuske <robert DOT nuske AT web DOT de>
6868
Robin Hübner <profan AT prfn DOT se>
69+
Ryo Hanafusa <ryo7gumi AT gmail DOT com>
6970
SeongJae Park <sj38 DOT park AT gmail DOT com>
7071
Thiago Avelino <thiago AT avelino DOT xxx>
7172
Thomas Fanninger <gogs DOT thomas AT fanninger DOT at>

options/locale/locale_ga-IE.ini

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3810,6 +3810,9 @@ runs.no_workflows.documentation=Le haghaidh tuilleadh eolais ar Gitea Actions, f
38103810
runs.no_runs=Níl aon rith ag an sreabhadh oibre fós.
38113811
runs.empty_commit_message=(teachtaireacht tiomantas folamh)
38123812
runs.expire_log_message=Glanadh logaí toisc go raibh siad ró-sean.
3813+
runs.delete=Scrios rith sreabha oibre
3814+
runs.delete.description=An bhfuil tú cinnte gur mian leat an rith sreabha oibre seo a scriosadh go buan? Ní féidir an gníomh seo a chealú.
3815+
runs.not_done=Níl an rith sreabha oibre seo críochnaithe.
38133816
38143817
workflow.disable=Díchumasaigh sreabhadh oibre
38153818
workflow.disable_success=D'éirigh le sreabhadh oibre '%s' a dhíchumasú.

routers/api/v1/shared/runners.go

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,28 @@ func ListRunners(ctx *context.APIContext, ownerID, repoID int64) {
6767
ctx.JSON(http.StatusOK, &res)
6868
}
6969

70+
func getRunnerByID(ctx *context.APIContext, ownerID, repoID, runnerID int64) (*actions_model.ActionRunner, bool) {
71+
if ownerID != 0 && repoID != 0 {
72+
setting.PanicInDevOrTesting("ownerID and repoID should not be both set")
73+
}
74+
75+
runner, err := actions_model.GetRunnerByID(ctx, runnerID)
76+
if err != nil {
77+
if errors.Is(err, util.ErrNotExist) {
78+
ctx.APIErrorNotFound("Runner not found")
79+
} else {
80+
ctx.APIErrorInternal(err)
81+
}
82+
return nil, false
83+
}
84+
85+
if !runner.EditableInContext(ownerID, repoID) {
86+
ctx.APIErrorNotFound("No permission to access this runner")
87+
return nil, false
88+
}
89+
return runner, true
90+
}
91+
7092
// GetRunner get the runner for api route validated ownerID and repoID
7193
// ownerID == 0 and repoID == 0 means any runner including global runners
7294
// ownerID == 0 and repoID != 0 means any runner for the given repo
@@ -77,13 +99,8 @@ func GetRunner(ctx *context.APIContext, ownerID, repoID, runnerID int64) {
7799
if ownerID != 0 && repoID != 0 {
78100
setting.PanicInDevOrTesting("ownerID and repoID should not be both set")
79101
}
80-
runner, err := actions_model.GetRunnerByID(ctx, runnerID)
81-
if err != nil {
82-
ctx.APIErrorNotFound(err)
83-
return
84-
}
85-
if !runner.EditableInContext(ownerID, repoID) {
86-
ctx.APIErrorNotFound("No permission to get this runner")
102+
runner, ok := getRunnerByID(ctx, ownerID, repoID, runnerID)
103+
if !ok {
87104
return
88105
}
89106
ctx.JSON(http.StatusOK, convert.ToActionRunner(ctx, runner))
@@ -96,20 +113,12 @@ func GetRunner(ctx *context.APIContext, ownerID, repoID, runnerID int64) {
96113
// ownerID != 0 and repoID != 0 undefined behavior
97114
// Access rights are checked at the API route level
98115
func DeleteRunner(ctx *context.APIContext, ownerID, repoID, runnerID int64) {
99-
if ownerID != 0 && repoID != 0 {
100-
setting.PanicInDevOrTesting("ownerID and repoID should not be both set")
101-
}
102-
runner, err := actions_model.GetRunnerByID(ctx, runnerID)
103-
if err != nil {
104-
ctx.APIErrorInternal(err)
105-
return
106-
}
107-
if !runner.EditableInContext(ownerID, repoID) {
108-
ctx.APIErrorNotFound("No permission to delete this runner")
116+
runner, ok := getRunnerByID(ctx, ownerID, repoID, runnerID)
117+
if !ok {
109118
return
110119
}
111120

112-
err = actions_model.DeleteRunner(ctx, runner.ID)
121+
err := actions_model.DeleteRunner(ctx, runner.ID)
113122
if err != nil {
114123
ctx.APIErrorInternal(err)
115124
return

routers/api/v1/utils/hook.go

Lines changed: 46 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"code.gitea.io/gitea/modules/setting"
1616
api "code.gitea.io/gitea/modules/structs"
1717
"code.gitea.io/gitea/modules/util"
18+
"code.gitea.io/gitea/modules/validation"
1819
webhook_module "code.gitea.io/gitea/modules/webhook"
1920
"code.gitea.io/gitea/services/context"
2021
webhook_service "code.gitea.io/gitea/services/webhook"
@@ -92,6 +93,10 @@ func checkCreateHookOption(ctx *context.APIContext, form *api.CreateHookOption)
9293
ctx.APIError(http.StatusUnprocessableEntity, "Invalid content type")
9394
return false
9495
}
96+
if !validation.IsValidURL(form.Config["url"]) {
97+
ctx.APIError(http.StatusUnprocessableEntity, "Invalid url")
98+
return false
99+
}
95100
return true
96101
}
97102

@@ -154,6 +159,41 @@ func pullHook(events []string, event string) bool {
154159
return util.SliceContainsString(events, event, true) || util.SliceContainsString(events, string(webhook_module.HookEventPullRequest), true)
155160
}
156161

162+
func updateHookEvents(events []string) webhook_module.HookEvents {
163+
if len(events) == 0 {
164+
events = []string{"push"}
165+
}
166+
hookEvents := make(webhook_module.HookEvents)
167+
hookEvents[webhook_module.HookEventCreate] = util.SliceContainsString(events, string(webhook_module.HookEventCreate), true)
168+
hookEvents[webhook_module.HookEventPush] = util.SliceContainsString(events, string(webhook_module.HookEventPush), true)
169+
hookEvents[webhook_module.HookEventDelete] = util.SliceContainsString(events, string(webhook_module.HookEventDelete), true)
170+
hookEvents[webhook_module.HookEventFork] = util.SliceContainsString(events, string(webhook_module.HookEventFork), true)
171+
hookEvents[webhook_module.HookEventRepository] = util.SliceContainsString(events, string(webhook_module.HookEventRepository), true)
172+
hookEvents[webhook_module.HookEventWiki] = util.SliceContainsString(events, string(webhook_module.HookEventWiki), true)
173+
hookEvents[webhook_module.HookEventRelease] = util.SliceContainsString(events, string(webhook_module.HookEventRelease), true)
174+
hookEvents[webhook_module.HookEventPackage] = util.SliceContainsString(events, string(webhook_module.HookEventPackage), true)
175+
hookEvents[webhook_module.HookEventStatus] = util.SliceContainsString(events, string(webhook_module.HookEventStatus), true)
176+
hookEvents[webhook_module.HookEventWorkflowJob] = util.SliceContainsString(events, string(webhook_module.HookEventWorkflowJob), true)
177+
178+
// Issues
179+
hookEvents[webhook_module.HookEventIssues] = issuesHook(events, "issues_only")
180+
hookEvents[webhook_module.HookEventIssueAssign] = issuesHook(events, string(webhook_module.HookEventIssueAssign))
181+
hookEvents[webhook_module.HookEventIssueLabel] = issuesHook(events, string(webhook_module.HookEventIssueLabel))
182+
hookEvents[webhook_module.HookEventIssueMilestone] = issuesHook(events, string(webhook_module.HookEventIssueMilestone))
183+
hookEvents[webhook_module.HookEventIssueComment] = issuesHook(events, string(webhook_module.HookEventIssueComment))
184+
185+
// Pull requests
186+
hookEvents[webhook_module.HookEventPullRequest] = pullHook(events, "pull_request_only")
187+
hookEvents[webhook_module.HookEventPullRequestAssign] = pullHook(events, string(webhook_module.HookEventPullRequestAssign))
188+
hookEvents[webhook_module.HookEventPullRequestLabel] = pullHook(events, string(webhook_module.HookEventPullRequestLabel))
189+
hookEvents[webhook_module.HookEventPullRequestMilestone] = pullHook(events, string(webhook_module.HookEventPullRequestMilestone))
190+
hookEvents[webhook_module.HookEventPullRequestComment] = pullHook(events, string(webhook_module.HookEventPullRequestComment))
191+
hookEvents[webhook_module.HookEventPullRequestReview] = pullHook(events, "pull_request_review")
192+
hookEvents[webhook_module.HookEventPullRequestReviewRequest] = pullHook(events, string(webhook_module.HookEventPullRequestReviewRequest))
193+
hookEvents[webhook_module.HookEventPullRequestSync] = pullHook(events, string(webhook_module.HookEventPullRequestSync))
194+
return hookEvents
195+
}
196+
157197
// addHook add the hook specified by `form`, `ownerID` and `repoID`. If there is
158198
// an error, write to `ctx` accordingly. Return (webhook, ok)
159199
func addHook(ctx *context.APIContext, form *api.CreateHookOption, ownerID, repoID int64) (*webhook.Webhook, bool) {
@@ -162,9 +202,6 @@ func addHook(ctx *context.APIContext, form *api.CreateHookOption, ownerID, repoI
162202
return nil, false
163203
}
164204

165-
if len(form.Events) == 0 {
166-
form.Events = []string{"push"}
167-
}
168205
if form.Config["is_system_webhook"] != "" {
169206
sw, err := strconv.ParseBool(form.Config["is_system_webhook"])
170207
if err != nil {
@@ -183,31 +220,7 @@ func addHook(ctx *context.APIContext, form *api.CreateHookOption, ownerID, repoI
183220
IsSystemWebhook: isSystemWebhook,
184221
HookEvent: &webhook_module.HookEvent{
185222
ChooseEvents: true,
186-
HookEvents: webhook_module.HookEvents{
187-
webhook_module.HookEventCreate: util.SliceContainsString(form.Events, string(webhook_module.HookEventCreate), true),
188-
webhook_module.HookEventDelete: util.SliceContainsString(form.Events, string(webhook_module.HookEventDelete), true),
189-
webhook_module.HookEventFork: util.SliceContainsString(form.Events, string(webhook_module.HookEventFork), true),
190-
webhook_module.HookEventIssues: issuesHook(form.Events, "issues_only"),
191-
webhook_module.HookEventIssueAssign: issuesHook(form.Events, string(webhook_module.HookEventIssueAssign)),
192-
webhook_module.HookEventIssueLabel: issuesHook(form.Events, string(webhook_module.HookEventIssueLabel)),
193-
webhook_module.HookEventIssueMilestone: issuesHook(form.Events, string(webhook_module.HookEventIssueMilestone)),
194-
webhook_module.HookEventIssueComment: issuesHook(form.Events, string(webhook_module.HookEventIssueComment)),
195-
webhook_module.HookEventPush: util.SliceContainsString(form.Events, string(webhook_module.HookEventPush), true),
196-
webhook_module.HookEventPullRequest: pullHook(form.Events, "pull_request_only"),
197-
webhook_module.HookEventPullRequestAssign: pullHook(form.Events, string(webhook_module.HookEventPullRequestAssign)),
198-
webhook_module.HookEventPullRequestLabel: pullHook(form.Events, string(webhook_module.HookEventPullRequestLabel)),
199-
webhook_module.HookEventPullRequestMilestone: pullHook(form.Events, string(webhook_module.HookEventPullRequestMilestone)),
200-
webhook_module.HookEventPullRequestComment: pullHook(form.Events, string(webhook_module.HookEventPullRequestComment)),
201-
webhook_module.HookEventPullRequestReview: pullHook(form.Events, "pull_request_review"),
202-
webhook_module.HookEventPullRequestReviewRequest: pullHook(form.Events, string(webhook_module.HookEventPullRequestReviewRequest)),
203-
webhook_module.HookEventPullRequestSync: pullHook(form.Events, string(webhook_module.HookEventPullRequestSync)),
204-
webhook_module.HookEventWiki: util.SliceContainsString(form.Events, string(webhook_module.HookEventWiki), true),
205-
webhook_module.HookEventRepository: util.SliceContainsString(form.Events, string(webhook_module.HookEventRepository), true),
206-
webhook_module.HookEventRelease: util.SliceContainsString(form.Events, string(webhook_module.HookEventRelease), true),
207-
webhook_module.HookEventPackage: util.SliceContainsString(form.Events, string(webhook_module.HookEventPackage), true),
208-
webhook_module.HookEventStatus: util.SliceContainsString(form.Events, string(webhook_module.HookEventStatus), true),
209-
webhook_module.HookEventWorkflowJob: util.SliceContainsString(form.Events, string(webhook_module.HookEventWorkflowJob), true),
210-
},
223+
HookEvents: updateHookEvents(form.Events),
211224
BranchFilter: form.BranchFilter,
212225
},
213226
IsActive: form.Active,
@@ -324,6 +337,10 @@ func EditRepoHook(ctx *context.APIContext, form *api.EditHookOption, hookID int6
324337
func editHook(ctx *context.APIContext, form *api.EditHookOption, w *webhook.Webhook) bool {
325338
if form.Config != nil {
326339
if url, ok := form.Config["url"]; ok {
340+
if !validation.IsValidURL(url) {
341+
ctx.APIError(http.StatusUnprocessableEntity, "Invalid url")
342+
return false
343+
}
327344
w.URL = url
328345
}
329346
if ct, ok := form.Config["content_type"]; ok {
@@ -352,19 +369,10 @@ func editHook(ctx *context.APIContext, form *api.EditHookOption, w *webhook.Webh
352369
}
353370

354371
// Update events
355-
if len(form.Events) == 0 {
356-
form.Events = []string{"push"}
357-
}
372+
w.HookEvents = updateHookEvents(form.Events)
358373
w.PushOnly = false
359374
w.SendEverything = false
360375
w.ChooseEvents = true
361-
w.HookEvents[webhook_module.HookEventCreate] = util.SliceContainsString(form.Events, string(webhook_module.HookEventCreate), true)
362-
w.HookEvents[webhook_module.HookEventPush] = util.SliceContainsString(form.Events, string(webhook_module.HookEventPush), true)
363-
w.HookEvents[webhook_module.HookEventDelete] = util.SliceContainsString(form.Events, string(webhook_module.HookEventDelete), true)
364-
w.HookEvents[webhook_module.HookEventFork] = util.SliceContainsString(form.Events, string(webhook_module.HookEventFork), true)
365-
w.HookEvents[webhook_module.HookEventRepository] = util.SliceContainsString(form.Events, string(webhook_module.HookEventRepository), true)
366-
w.HookEvents[webhook_module.HookEventWiki] = util.SliceContainsString(form.Events, string(webhook_module.HookEventWiki), true)
367-
w.HookEvents[webhook_module.HookEventRelease] = util.SliceContainsString(form.Events, string(webhook_module.HookEventRelease), true)
368376
w.BranchFilter = form.BranchFilter
369377

370378
err := w.SetHeaderAuthorization(form.AuthorizationHeader)
@@ -373,23 +381,6 @@ func editHook(ctx *context.APIContext, form *api.EditHookOption, w *webhook.Webh
373381
return false
374382
}
375383

376-
// Issues
377-
w.HookEvents[webhook_module.HookEventIssues] = issuesHook(form.Events, "issues_only")
378-
w.HookEvents[webhook_module.HookEventIssueAssign] = issuesHook(form.Events, string(webhook_module.HookEventIssueAssign))
379-
w.HookEvents[webhook_module.HookEventIssueLabel] = issuesHook(form.Events, string(webhook_module.HookEventIssueLabel))
380-
w.HookEvents[webhook_module.HookEventIssueMilestone] = issuesHook(form.Events, string(webhook_module.HookEventIssueMilestone))
381-
w.HookEvents[webhook_module.HookEventIssueComment] = issuesHook(form.Events, string(webhook_module.HookEventIssueComment))
382-
383-
// Pull requests
384-
w.HookEvents[webhook_module.HookEventPullRequest] = pullHook(form.Events, "pull_request_only")
385-
w.HookEvents[webhook_module.HookEventPullRequestAssign] = pullHook(form.Events, string(webhook_module.HookEventPullRequestAssign))
386-
w.HookEvents[webhook_module.HookEventPullRequestLabel] = pullHook(form.Events, string(webhook_module.HookEventPullRequestLabel))
387-
w.HookEvents[webhook_module.HookEventPullRequestMilestone] = pullHook(form.Events, string(webhook_module.HookEventPullRequestMilestone))
388-
w.HookEvents[webhook_module.HookEventPullRequestComment] = pullHook(form.Events, string(webhook_module.HookEventPullRequestComment))
389-
w.HookEvents[webhook_module.HookEventPullRequestReview] = pullHook(form.Events, "pull_request_review")
390-
w.HookEvents[webhook_module.HookEventPullRequestReviewRequest] = pullHook(form.Events, string(webhook_module.HookEventPullRequestReviewRequest))
391-
w.HookEvents[webhook_module.HookEventPullRequestSync] = pullHook(form.Events, string(webhook_module.HookEventPullRequestSync))
392-
393384
if err := w.UpdateEvent(); err != nil {
394385
ctx.APIErrorInternal(err)
395386
return false

0 commit comments

Comments
 (0)