package luajit /* #include #include */ import "C" import ( "fmt" "strings" ) // LuaError represents an enhanced error from the Lua state type LuaError struct { Code int Message string File string Line int StackTrace string Context string } func (e *LuaError) Error() string { var parts []string if e.File != "" && e.Line > 0 { parts = append(parts, fmt.Sprintf("%s:%d", e.File, e.Line)) } if e.Context != "" { parts = append(parts, fmt.Sprintf("[%s]", e.Context)) } parts = append(parts, e.Message) if e.Code != 0 { parts = append(parts, fmt.Sprintf("(code=%d)", e.Code)) } result := strings.Join(parts, " ") if e.StackTrace != "" { result += "\n" + e.StackTrace } return result } // GetStackTrace returns the current Lua stack trace func (s *State) GetStackTrace() string { s.GetGlobal("debug") if !s.IsTable(-1) { s.Pop(1) return "debug table not available" } s.GetField(-1, "traceback") if !s.IsFunction(-1) { s.Pop(2) return "debug.traceback not available" } s.Call(0, 1) trace := s.ToString(-1) s.Pop(1) return trace } // GetErrorInfo extracts detailed error information from the Lua stack func (s *State) GetErrorInfo(context string) *LuaError { if s.GetTop() == 0 { return &LuaError{ Message: "unknown error (empty stack)", Context: context, } } message := s.ToString(-1) // Parse file:line from common Lua error format var file string var line int if colonPos := strings.Index(message, ":"); colonPos > 0 { beforeColon := message[:colonPos] afterColon := message[colonPos+1:] if secondColonPos := strings.Index(afterColon, ":"); secondColonPos > 0 { file = beforeColon if n, err := fmt.Sscanf(afterColon[:secondColonPos], "%d", &line); n == 1 && err == nil { message = strings.TrimSpace(afterColon[secondColonPos+1:]) } } } stackTrace := s.GetStackTrace() return &LuaError{ Message: message, File: file, Line: line, StackTrace: stackTrace, Context: context, } } // CreateLuaError creates a LuaError with full context information func (s *State) CreateLuaError(code int, context string) *LuaError { err := s.GetErrorInfo(context) err.Code = code return err } // PushError pushes an error string and returns -1 func (s *State) PushError(format string, args ...any) int { s.PushString(fmt.Sprintf(format, args...)) return -1 }