improve error reporting
This commit is contained in:
parent
2bdf7cfd4a
commit
6a2eb9df63
20
bytecode.go
20
bytecode.go
@ -102,10 +102,7 @@ func (s *State) LoadBytecode(bytecode []byte, name string) error {
|
||||
)
|
||||
|
||||
if status != 0 {
|
||||
err := &LuaError{
|
||||
Code: int(status),
|
||||
Message: s.ToString(-1),
|
||||
}
|
||||
err := s.CreateLuaError(int(status), fmt.Sprintf("LoadBytecode(%s)", name))
|
||||
s.Pop(1) // Remove error message
|
||||
return err
|
||||
}
|
||||
@ -123,10 +120,7 @@ func (s *State) RunBytecode() error {
|
||||
func (s *State) RunBytecodeWithResults(nresults int) error {
|
||||
status := C.lua_pcall(s.L, 0, C.int(nresults), 0)
|
||||
if status != 0 {
|
||||
err := &LuaError{
|
||||
Code: int(status),
|
||||
Message: s.ToString(-1),
|
||||
}
|
||||
err := s.CreateLuaError(int(status), fmt.Sprintf("RunBytecode(nresults=%d)", nresults))
|
||||
s.Pop(1) // Remove error message
|
||||
return err
|
||||
}
|
||||
@ -152,10 +146,7 @@ func (s *State) LoadAndRunBytecode(bytecode []byte, name string) error {
|
||||
)
|
||||
|
||||
if status != 0 {
|
||||
err := &LuaError{
|
||||
Code: int(status),
|
||||
Message: s.ToString(-1),
|
||||
}
|
||||
err := s.CreateLuaError(int(status), fmt.Sprintf("LoadAndRunBytecode(%s)", name))
|
||||
s.Pop(1) // Remove error message
|
||||
return err
|
||||
}
|
||||
@ -182,10 +173,7 @@ func (s *State) LoadAndRunBytecodeWithResults(bytecode []byte, name string, nres
|
||||
)
|
||||
|
||||
if status != 0 {
|
||||
err := &LuaError{
|
||||
Code: int(status),
|
||||
Message: s.ToString(-1),
|
||||
}
|
||||
err := s.CreateLuaError(int(status), fmt.Sprintf("LoadAndRunBytecodeWithResults(%s, nresults=%d)", name, nresults))
|
||||
s.Pop(1) // Remove error message
|
||||
return err
|
||||
}
|
||||
|
82
stack.go
82
stack.go
@ -5,16 +5,45 @@ package luajit
|
||||
#include <lauxlib.h>
|
||||
*/
|
||||
import "C"
|
||||
import "fmt"
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// LuaError represents an error from the Lua state
|
||||
// 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 {
|
||||
return fmt.Sprintf("lua error (code=%d): %s", e.Code, e.Message)
|
||||
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
|
||||
}
|
||||
|
||||
// Stack management constants from lua.h
|
||||
@ -45,3 +74,50 @@ func (s *State) GetStackTrace() string {
|
||||
|
||||
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 {
|
||||
// Strip the file:line part from message for cleaner display
|
||||
message = strings.TrimSpace(afterColon[secondColonPos+1:])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get stack trace
|
||||
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
|
||||
}
|
||||
|
30
wrapper.go
30
wrapper.go
@ -342,10 +342,7 @@ func (s *State) LoadString(code string) error {
|
||||
|
||||
status := C.luaL_loadstring(s.L, ccode)
|
||||
if status != 0 {
|
||||
err := &LuaError{
|
||||
Code: int(status),
|
||||
Message: s.ToString(-1),
|
||||
}
|
||||
err := s.CreateLuaError(int(status), "LoadString")
|
||||
s.Pop(1) // Remove error message
|
||||
return err
|
||||
}
|
||||
@ -359,10 +356,7 @@ func (s *State) LoadFile(filename string) error {
|
||||
|
||||
status := C.luaL_loadfile(s.L, cfilename)
|
||||
if status != 0 {
|
||||
err := &LuaError{
|
||||
Code: int(status),
|
||||
Message: s.ToString(-1),
|
||||
}
|
||||
err := s.CreateLuaError(int(status), fmt.Sprintf("LoadFile(%s)", filename))
|
||||
s.Pop(1) // Remove error message
|
||||
return err
|
||||
}
|
||||
@ -373,10 +367,7 @@ func (s *State) LoadFile(filename string) error {
|
||||
func (s *State) Call(nargs, nresults int) error {
|
||||
status := C.lua_pcall(s.L, C.int(nargs), C.int(nresults), 0)
|
||||
if status != 0 {
|
||||
err := &LuaError{
|
||||
Code: int(status),
|
||||
Message: s.ToString(-1),
|
||||
}
|
||||
err := s.CreateLuaError(int(status), fmt.Sprintf("Call(%d,%d)", nargs, nresults))
|
||||
s.Pop(1) // Remove error message
|
||||
return err
|
||||
}
|
||||
@ -390,10 +381,7 @@ func (s *State) DoString(code string) error {
|
||||
|
||||
status := C.do_string(s.L, ccode)
|
||||
if status != 0 {
|
||||
err := &LuaError{
|
||||
Code: int(status),
|
||||
Message: s.ToString(-1),
|
||||
}
|
||||
err := s.CreateLuaError(int(status), "DoString")
|
||||
s.Pop(1) // Remove error message
|
||||
return err
|
||||
}
|
||||
@ -407,10 +395,7 @@ func (s *State) DoFile(filename string) error {
|
||||
|
||||
status := C.do_file(s.L, cfilename)
|
||||
if status != 0 {
|
||||
err := &LuaError{
|
||||
Code: int(status),
|
||||
Message: s.ToString(-1),
|
||||
}
|
||||
err := s.CreateLuaError(int(status), fmt.Sprintf("DoFile(%s)", filename))
|
||||
s.Pop(1) // Remove error message
|
||||
return err
|
||||
}
|
||||
@ -426,10 +411,7 @@ func (s *State) Execute(code string) (int, error) {
|
||||
|
||||
status := C.execute_with_results(s.L, ccode, 1) // store_results=true
|
||||
if status != 0 {
|
||||
err := &LuaError{
|
||||
Code: int(status),
|
||||
Message: s.ToString(-1),
|
||||
}
|
||||
err := s.CreateLuaError(int(status), "Execute")
|
||||
s.Pop(1) // Remove error message
|
||||
return 0, err
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user