add GoErr
This commit is contained in:
parent
7bae8c77a2
commit
1a7cdbad3f
@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"apigo.cc/gojs/common"
|
||||
"apigo.cc/gojs/goja"
|
||||
"github.com/ssgo/u"
|
||||
)
|
||||
@ -240,7 +241,7 @@ func go2js(in any, n int) any {
|
||||
// 抛出异常
|
||||
if err, ok := outValue.Interface().(error); ok {
|
||||
panic(vm.NewGoError(err))
|
||||
} else if err, ok := outValue.Interface().(*u.Err); ok {
|
||||
} else if err, ok := outValue.Interface().(*common.GoErr); ok {
|
||||
panic(vm.NewGoError(err))
|
||||
} else {
|
||||
panic(vm.NewGoError(errors.New(u.String(outValue.Interface()))))
|
||||
|
||||
10
common/goerr.go
Normal file
10
common/goerr.go
Normal file
@ -0,0 +1,10 @@
|
||||
package common
|
||||
|
||||
type GoErr struct {
|
||||
Message string
|
||||
Stack []string
|
||||
}
|
||||
|
||||
func (e *GoErr) Error() string {
|
||||
return e.Message
|
||||
}
|
||||
2
go.mod
2
go.mod
@ -8,7 +8,7 @@ require (
|
||||
github.com/google/pprof v0.0.0-20250607225305-033d6d78b36a
|
||||
github.com/ssgo/log v1.7.7
|
||||
github.com/ssgo/tool v0.4.29
|
||||
github.com/ssgo/u v1.7.19
|
||||
github.com/ssgo/u v1.7.21
|
||||
golang.org/x/net v0.41.0
|
||||
golang.org/x/text v0.26.0
|
||||
)
|
||||
|
||||
@ -20,6 +20,7 @@ import (
|
||||
"github.com/ssgo/u"
|
||||
"golang.org/x/text/collate"
|
||||
|
||||
"apigo.cc/gojs/common"
|
||||
js_ast "apigo.cc/gojs/goja/ast"
|
||||
"apigo.cc/gojs/goja/file"
|
||||
"apigo.cc/gojs/goja/parser"
|
||||
@ -554,7 +555,7 @@ func (r *Runtime) NewTypeError(args ...interface{}) *Object {
|
||||
func (r *Runtime) NewGoError(err error) *Object {
|
||||
// 打印Go代码的调用栈
|
||||
callStacks := make([]string, 0)
|
||||
if err, ok := err.(*u.Err); ok && err.Stack != nil {
|
||||
if err, ok := err.(*common.GoErr); ok && err.Stack != nil {
|
||||
for _, stack := range err.Stack {
|
||||
if strings.Contains(stack, "/goja/") {
|
||||
continue
|
||||
|
||||
96
gojs.go
96
gojs.go
@ -8,11 +8,13 @@ import (
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"apigo.cc/gojs/common"
|
||||
"apigo.cc/gojs/goja"
|
||||
"apigo.cc/gojs/goja_nodejs/require"
|
||||
"github.com/ssgo/log"
|
||||
@ -48,7 +50,7 @@ var modulesLock = sync.RWMutex{}
|
||||
var runInMains = []func(){}
|
||||
var runInMainsLock = sync.RWMutex{}
|
||||
|
||||
type Error struct {
|
||||
type JsError struct {
|
||||
Message string
|
||||
Stack []string
|
||||
fullMessage string
|
||||
@ -56,31 +58,31 @@ type Error struct {
|
||||
exceprion *goja.Exception
|
||||
}
|
||||
|
||||
func (e *Error) Error() string {
|
||||
func (e *JsError) Error() string {
|
||||
return e.fullMessage
|
||||
}
|
||||
|
||||
func (e *Error) GetError() error {
|
||||
func (e *JsError) GetError() error {
|
||||
return e.err
|
||||
}
|
||||
|
||||
func (e *Error) GetException() error {
|
||||
func (e *JsError) GetException() error {
|
||||
return e.exceprion
|
||||
}
|
||||
|
||||
func GetError(err error) *Error {
|
||||
func GetJsError(err error) *JsError {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
return MakeError(err).(*Error)
|
||||
return MakeJsError(err).(*JsError)
|
||||
}
|
||||
|
||||
func MakeError(err error) error {
|
||||
func MakeJsError(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
var newErr *Error
|
||||
if gojsErr, ok := err.(*Error); ok {
|
||||
var newErr *JsError
|
||||
if gojsErr, ok := err.(*JsError); ok {
|
||||
newErr = gojsErr
|
||||
} else if gojaErr, ok := err.(*goja.Exception); ok {
|
||||
stack := make([]string, len(gojaErr.Stack()))
|
||||
@ -88,16 +90,50 @@ func MakeError(err error) error {
|
||||
stack[i] = fmt.Sprintf("%s @%s", v.Position().String(), v.FuncName())
|
||||
}
|
||||
msg, fullMsg, stack1 := parseMessageAndStack(gojaErr.Value().String(), stack)
|
||||
newErr = &Error{Message: msg, fullMessage: fullMsg, Stack: stack1, err: err, exceprion: gojaErr}
|
||||
newErr = &JsError{Message: msg, fullMessage: fullMsg, Stack: stack1, err: err, exceprion: gojaErr}
|
||||
} else {
|
||||
msg, fullMsg, stack := parseMessageAndStack(err.Error(), []string{})
|
||||
newErr = &Error{Message: msg, fullMessage: fullMsg, Stack: stack, err: err, exceprion: nil}
|
||||
newErr = &JsError{Message: msg, fullMessage: fullMsg, Stack: stack, err: err, exceprion: nil}
|
||||
}
|
||||
// newErr.Message = strings.ReplaceAll(newErr.Message, "GoError: ", "")
|
||||
newErr.fullMessage = strings.ReplaceAll(newErr.fullMessage, "GoError: ", "")
|
||||
return newErr
|
||||
}
|
||||
|
||||
func Errf(format string, args ...any) *common.GoErr {
|
||||
return Err(fmt.Sprintf(format, args...))
|
||||
}
|
||||
|
||||
func Err(err any) *common.GoErr {
|
||||
errStr := ""
|
||||
if e, ok := err.(error); ok {
|
||||
errStr = e.Error()
|
||||
} else {
|
||||
errStr = u.String(err)
|
||||
}
|
||||
callStacks := make([]string, 0)
|
||||
for i := 1; i < 50; i++ {
|
||||
_, file, line, ok := runtime.Caller(i)
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
if strings.Contains(file, "/go/src/") {
|
||||
continue
|
||||
}
|
||||
if strings.Contains(file, "/ssgo/log") {
|
||||
continue
|
||||
}
|
||||
if strings.Contains(file, "/ssgo") {
|
||||
file = "**" + file[strings.LastIndex(file, "/ssgo"):]
|
||||
}
|
||||
callStacks = append(callStacks, fmt.Sprintf("%s:%d", file, line))
|
||||
}
|
||||
return &common.GoErr{
|
||||
Message: errStr,
|
||||
Stack: callStacks,
|
||||
}
|
||||
}
|
||||
|
||||
func parseMessageAndStack(msg string, stack []string) (string, string, []string) {
|
||||
if strings.Contains(msg, "|:|") {
|
||||
a := strings.Split(msg, "|:|")
|
||||
@ -241,7 +277,7 @@ func RunFile(file string, args ...any) (any, error) {
|
||||
if code, err := u.ReadFile(file); err == nil {
|
||||
return Run(code, file, args...)
|
||||
} else {
|
||||
return nil, MakeError(err)
|
||||
return nil, MakeJsError(err)
|
||||
}
|
||||
}
|
||||
|
||||
@ -252,7 +288,7 @@ func Run(code string, refFile string, args ...any) (any, error) {
|
||||
if err == nil {
|
||||
r, err = rt.RunMain(args...)
|
||||
}
|
||||
return r, MakeError(err)
|
||||
return r, MakeJsError(err)
|
||||
}
|
||||
|
||||
func RunProgram(prg *Program, args ...any) (any, error) {
|
||||
@ -262,14 +298,14 @@ func RunProgram(prg *Program, args ...any) (any, error) {
|
||||
if err == nil {
|
||||
r, err = rt.RunMain(args...)
|
||||
}
|
||||
return r, MakeError(err)
|
||||
return r, MakeJsError(err)
|
||||
}
|
||||
|
||||
func CompileFile(file string) (*Program, error) {
|
||||
if code, err := u.ReadFile(file); err == nil {
|
||||
return CompileMain(code, file)
|
||||
} else {
|
||||
return nil, MakeError(err)
|
||||
return nil, MakeJsError(err)
|
||||
}
|
||||
}
|
||||
|
||||
@ -279,13 +315,13 @@ func CompileMain(code string, refFile string) (*Program, error) {
|
||||
code = "function main(...Args){" + code + "}"
|
||||
}
|
||||
p, err := goja.Compile(refFile, code, false)
|
||||
return &Program{prg: p, imports: imports, startFile: refFile}, MakeError(err)
|
||||
return &Program{prg: p, imports: imports, startFile: refFile}, MakeJsError(err)
|
||||
}
|
||||
|
||||
func CompileCode(code string, refFile string) (*Program, error) {
|
||||
imports := makeImports(&code)
|
||||
p, err := goja.Compile(refFile, code, false)
|
||||
return &Program{prg: p, imports: imports, startFile: refFile}, MakeError(err)
|
||||
return &Program{prg: p, imports: imports, startFile: refFile}, MakeJsError(err)
|
||||
}
|
||||
|
||||
var importModMatcher = regexp.MustCompile(`(?im)^\s*import\s+(.+?)\s+from\s+['"](.+?)['"]`)
|
||||
@ -369,7 +405,7 @@ func (rt *Runtime) requireMod(modName, realModName string, inVM bool) error {
|
||||
rt.unlock()
|
||||
}
|
||||
if err != nil {
|
||||
return MakeError(err)
|
||||
return MakeJsError(err)
|
||||
}
|
||||
rt.required[modName] = true
|
||||
}
|
||||
@ -401,7 +437,7 @@ func (rt *Runtime) requireAllMod() error {
|
||||
}
|
||||
rt.unlock()
|
||||
if err != nil {
|
||||
return MakeError(err)
|
||||
return MakeJsError(err)
|
||||
}
|
||||
rt.required[modName] = true
|
||||
}
|
||||
@ -568,7 +604,7 @@ func (rt *Runtime) StartFromCode(code, refFile string) error {
|
||||
_, err := rt.SafeRunScript(rt.file, rt.code)
|
||||
rt.unlock()
|
||||
if err != nil {
|
||||
return MakeError(err)
|
||||
return MakeJsError(err)
|
||||
} else {
|
||||
rt.started = true
|
||||
return nil
|
||||
@ -580,7 +616,7 @@ func (rt *Runtime) SafeRunProgram(prg *Program) (v goja.Value, err error) {
|
||||
if x := recover(); x != nil {
|
||||
if e, ok := x.(error); ok {
|
||||
err = e
|
||||
if e2 := GetError(err); e2 != nil {
|
||||
if e2 := GetJsError(err); e2 != nil {
|
||||
err = e2
|
||||
GetLogger(rt.vm).Error(e2.Error(), "stack", e2.Stack)
|
||||
}
|
||||
@ -597,7 +633,7 @@ func (rt *Runtime) SafeRunScript(name, src string) (v goja.Value, err error) {
|
||||
if x := recover(); x != nil {
|
||||
if e, ok := x.(error); ok {
|
||||
err = e
|
||||
if e2 := GetError(err); e2 != nil {
|
||||
if e2 := GetJsError(err); e2 != nil {
|
||||
err = e2
|
||||
GetLogger(rt.vm).Error(e2.Error(), "stack", e2.Stack)
|
||||
}
|
||||
@ -614,7 +650,7 @@ func (rt *Runtime) SafeRunString(str string) (v goja.Value, err error) {
|
||||
if x := recover(); x != nil {
|
||||
if e, ok := x.(error); ok {
|
||||
err = e
|
||||
if e2 := GetError(err); e2 != nil {
|
||||
if e2 := GetJsError(err); e2 != nil {
|
||||
err = e2
|
||||
GetLogger(rt.vm).Error(e2.Error(), "stack", e2.Stack)
|
||||
}
|
||||
@ -651,7 +687,7 @@ func (rt *Runtime) StartFromProgram(prg *Program) error {
|
||||
_, err := rt.SafeRunProgram(prg)
|
||||
rt.unlock()
|
||||
if err != nil {
|
||||
return MakeError(err)
|
||||
return MakeJsError(err)
|
||||
} else {
|
||||
rt.started = true
|
||||
return nil
|
||||
@ -666,7 +702,7 @@ func (rt *Runtime) RunMain(args ...any) (any, error) {
|
||||
// 解析参数
|
||||
for i, arg := range args {
|
||||
if str, ok := arg.(string); ok {
|
||||
var v interface{}
|
||||
var v any
|
||||
if err := json.Unmarshal([]byte(str), &v); err == nil {
|
||||
args[i] = v
|
||||
}
|
||||
@ -677,7 +713,7 @@ func (rt *Runtime) RunMain(args ...any) (any, error) {
|
||||
err := rt.vm.Set("__args", args)
|
||||
rt.unlock()
|
||||
if err != nil {
|
||||
return nil, MakeError(err)
|
||||
return nil, MakeJsError(err)
|
||||
}
|
||||
rt.lock()
|
||||
r, err := rt.SafeRunScript("main", "main(...__args)")
|
||||
@ -689,7 +725,7 @@ func (rt *Runtime) RunVM(callback func(vm *goja.Runtime) (any, error)) (any, err
|
||||
rt.lock()
|
||||
r, err := callback(rt.vm)
|
||||
rt.unlock()
|
||||
return r, MakeError(err)
|
||||
return r, MakeJsError(err)
|
||||
}
|
||||
|
||||
func (rt *Runtime) SetGoData(name string, value any) {
|
||||
@ -707,7 +743,7 @@ func (rt *Runtime) GetGoData(name string) any {
|
||||
func (rt *Runtime) Set(name string, value any) error {
|
||||
rt.lock()
|
||||
defer rt.unlock()
|
||||
return MakeError(rt.vm.Set(name, value))
|
||||
return MakeJsError(rt.vm.Set(name, value))
|
||||
}
|
||||
|
||||
func (rt *Runtime) SetGlobal(global Map) error {
|
||||
@ -716,7 +752,7 @@ func (rt *Runtime) SetGlobal(global Map) error {
|
||||
defer rt.unlock()
|
||||
for k, v := range global {
|
||||
if err = rt.vm.Set(k, v); err != nil {
|
||||
return MakeError(err)
|
||||
return MakeJsError(err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@ -768,7 +804,7 @@ func makeResult(r goja.Value, err error) (any, error) {
|
||||
result = r.Export()
|
||||
}
|
||||
}
|
||||
return result, MakeError(err)
|
||||
return result, MakeJsError(err)
|
||||
}
|
||||
|
||||
type WatchRunner struct {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user