diff --git a/controllers/account.go b/controllers/account.go index 62d7ce22..39712974 100644 --- a/controllers/account.go +++ b/controllers/account.go @@ -210,7 +210,7 @@ func (c *ApiController) Signup() { record := object.NewRecord(c.Ctx) record.Organization = application.Organization record.User = user.Name - go object.AddRecord(record) + util.SafeGoroutine(func() {object.AddRecord(record)}) userId := fmt.Sprintf("%s/%s", user.Owner, user.Name) util.LogInfo(c.Ctx, "API: [%s] is signed up as new user", userId) diff --git a/controllers/auth.go b/controllers/auth.go index f465c396..55f9cf3e 100644 --- a/controllers/auth.go +++ b/controllers/auth.go @@ -248,7 +248,7 @@ func (c *ApiController) Login() { record := object.NewRecord(c.Ctx) record.Organization = application.Organization record.User = user.Name - go object.AddRecord(record) + util.SafeGoroutine(func() {object.AddRecord(record)}) } } else if form.Provider != "" { application := object.GetApplication(fmt.Sprintf("admin/%s", form.Application)) @@ -341,7 +341,7 @@ func (c *ApiController) Login() { record := object.NewRecord(c.Ctx) record.Organization = application.Organization record.User = user.Name - go object.AddRecord(record) + util.SafeGoroutine(func() {object.AddRecord(record)}) } else if provider.Category == "OAuth" { // Sign up via OAuth if !application.EnableSignUp { @@ -390,7 +390,7 @@ func (c *ApiController) Login() { record := object.NewRecord(c.Ctx) record.Organization = application.Organization record.User = user.Name - go object.AddRecord(record) + util.SafeGoroutine(func() {object.AddRecord(record)}) } else if provider.Category == "SAML" { resp = &Response{Status: "error", Msg: "The account does not exist"} } diff --git a/main.go b/main.go index 46979845..939e60cc 100644 --- a/main.go +++ b/main.go @@ -27,6 +27,7 @@ import ( "github.com/casdoor/casdoor/proxy" "github.com/casdoor/casdoor/routers" _ "github.com/casdoor/casdoor/routers" + "github.com/casdoor/casdoor/util" ) func main() { @@ -40,7 +41,7 @@ func main() { proxy.InitHttpClient() authz.InitAuthz() - go object.RunSyncUsersJob() + util.SafeGoroutine(func() {object.RunSyncUsersJob()}) //beego.DelStaticPath("/static") beego.SetStaticPath("/static", "web/build/static") diff --git a/object/ldap_autosync.go b/object/ldap_autosync.go index c6611faf..f6935664 100644 --- a/object/ldap_autosync.go +++ b/object/ldap_autosync.go @@ -6,6 +6,7 @@ import ( "time" "github.com/astaxie/beego/logs" + "github.com/casdoor/casdoor/util" ) type LdapAutoSynchronizer struct { @@ -47,7 +48,7 @@ func (l *LdapAutoSynchronizer) StartAutoSync(ldapId string) error { stopChan := make(chan struct{}) l.ldapIdToStopChan[ldapId] = stopChan logs.Info(fmt.Sprintf("autoSync started for %s", ldap.Id)) - go l.syncRoutine(ldap, stopChan) + util.SafeGoroutine(func() {l.syncRoutine(ldap, stopChan)}) return nil } diff --git a/routers/record.go b/routers/record.go index e0859589..8bfe988f 100644 --- a/routers/record.go +++ b/routers/record.go @@ -65,5 +65,5 @@ func RecordMessage(ctx *context.Context) { record.Organization, record.User = util.GetOwnerAndNameFromId(userId) } - go object.AddRecord(record) + util.SafeGoroutine(func() {object.AddRecord(record)}) } diff --git a/util/util.go b/util/util.go new file mode 100644 index 00000000..086d3423 --- /dev/null +++ b/util/util.go @@ -0,0 +1,38 @@ +// Copyright 2022 The Casdoor Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package util + +import ( + "fmt" + + "github.com/astaxie/beego/logs" +) + +func SafeGoroutine(fn func()) { + var err error + go func() { + defer func() { + if r := recover(); r != nil { + var ok bool + err, ok = r.(error) + if !ok { + err = fmt.Errorf("%v", r) + } + logs.Error("goroutine panic: %v", err) + } + }() + fn() + }() +}