Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions frame/g/g_func.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ func Go(
ctx context.Context,
goroutineFunc func(ctx context.Context),
recoverFunc func(ctx context.Context, exception error),
finallyFunc ...func(ctx context.Context),
) {
gutil.Go(ctx, goroutineFunc, recoverFunc)
gutil.Go(ctx, goroutineFunc, recoverFunc, finallyFunc...)
}

// NewVar returns a gvar.Var.
Expand Down Expand Up @@ -83,16 +84,16 @@ func Throw(exception interface{}) {

// Try implements try... logistics using internal panic...recover.
// It returns error if any exception occurs, or else it returns nil.
func Try(ctx context.Context, try func(ctx context.Context)) (err error) {
return gutil.Try(ctx, try)
func Try(ctx context.Context, try func(ctx context.Context), finally ...func(ctx context.Context)) (err error) {
return gutil.Try(ctx, try, finally...)
}

// TryCatch implements try...catch... logistics using internal panic...recover.
// It automatically calls function `catch` if any exception occurs and passes the exception as an error.
//
// But, note that, if function `catch` also throws panic, the current goroutine will panic.
func TryCatch(ctx context.Context, try func(ctx context.Context), catch func(ctx context.Context, exception error)) {
gutil.TryCatch(ctx, try, catch)
func TryCatch(ctx context.Context, try func(ctx context.Context), catch func(ctx context.Context, exception error), finally ...func(ctx context.Context)) {
gutil.TryCatch(ctx, try, catch, finally...)
}

// IsNil checks whether given `value` is nil.
Expand Down
3 changes: 2 additions & 1 deletion util/gutil/gutil_goroutine.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ func Go(
ctx context.Context,
goroutineFunc func(ctx context.Context),
recoverFunc func(ctx context.Context, exception error),
finallyFunc ...func(ctx context.Context),
) {
if goroutineFunc == nil {
return
}
go TryCatch(ctx, goroutineFunc, recoverFunc)
go TryCatch(ctx, goroutineFunc, recoverFunc, finallyFunc...)
}
10 changes: 8 additions & 2 deletions util/gutil/gutil_try_catch.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,13 @@ func Throw(exception interface{}) {

// Try implements try... logistics using internal panic...recover.
// It returns error if any exception occurs, or else it returns nil.
func Try(ctx context.Context, try func(ctx context.Context)) (err error) {
func Try(ctx context.Context, try func(ctx context.Context), finally ...func(ctx context.Context)) (err error) {
if try == nil {
return
}
if len(finally) > 0 && finally[0] != nil {
defer finally[0](ctx)
}
defer func() {
if exception := recover(); exception != nil {
if v, ok := exception.(error); ok && gerror.HasStack(v) {
Expand All @@ -42,10 +45,13 @@ func Try(ctx context.Context, try func(ctx context.Context)) (err error) {
// If `catch` is given nil, it ignores the panic from `try` and no panic will throw to parent goroutine.
//
// But, note that, if function `catch` also throws panic, the current goroutine will panic.
func TryCatch(ctx context.Context, try func(ctx context.Context), catch func(ctx context.Context, exception error)) {
func TryCatch(ctx context.Context, try func(ctx context.Context), catch func(ctx context.Context, exception error), finally ...func(ctx context.Context)) {
if try == nil {
return
}
if len(finally) > 0 && finally[0] != nil {
defer finally[0](ctx)
}
if exception := Try(ctx, try); exception != nil && catch != nil {
catch(ctx, exception)
}
Expand Down
13 changes: 8 additions & 5 deletions util/gutil/gutil_z_unit_goroutine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ func Test_Go(t *testing.T) {
)
wg.Add(1)
gutil.Go(ctx, func(ctx context.Context) {
defer wg.Done()
array.Append(1)
}, nil)
}, nil, func(ctx context.Context) {
wg.Done()
})
wg.Wait()
t.Assert(array.Len(), 1)
})
Expand All @@ -38,10 +39,11 @@ func Test_Go(t *testing.T) {
)
wg.Add(1)
gutil.Go(ctx, func(ctx context.Context) {
defer wg.Done()
panic("error")
array.Append(1)
}, nil)
}, nil, func(ctx context.Context) {
wg.Done()
})
wg.Wait()
t.Assert(array.Len(), 0)
})
Expand All @@ -54,8 +56,9 @@ func Test_Go(t *testing.T) {
gutil.Go(ctx, func(ctx context.Context) {
panic("error")
}, func(ctx context.Context, exception error) {
defer wg.Done()
array.Append(exception)
}, func(ctx context.Context) {
wg.Done()
})
wg.Wait()
t.Assert(array.Len(), 1)
Expand Down
9 changes: 9 additions & 0 deletions util/gutil/gutil_z_unit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,13 @@ func Test_Try(t *testing.T) {
})
gtest.C(t, func(t *gtest.T) {
s := `gutil Try test`
r := `gutil Finally test`
t.Assert(gutil.Try(ctx, func(ctx context.Context) {
panic(gerror.New(s))
}, func(ctx context.Context) {
r = `gutil Finally test passed`
}), s)
t.Assert(r, `gutil Finally test passed`)
})
}

Expand All @@ -53,12 +57,17 @@ func Test_TryCatch(t *testing.T) {
})

gtest.C(t, func(t *gtest.T) {
r := `gutil Finally test`
gutil.TryCatch(ctx, func(ctx context.Context) {
panic(gerror.New("gutil TryCatch test"))

}, func(ctx context.Context, err error) {
t.Assert(err, "gutil TryCatch test")
r = `gutil Finally test catch`
}, func(ctx context.Context) {
r = `gutil Finally test passed`
})
t.Assert(r, `gutil Finally test passed`)
})
}

Expand Down
Loading