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 {
|
if status != 0 {
|
||||||
err := &LuaError{
|
err := s.CreateLuaError(int(status), fmt.Sprintf("LoadBytecode(%s)", name))
|
||||||
Code: int(status),
|
|
||||||
Message: s.ToString(-1),
|
|
||||||
}
|
|
||||||
s.Pop(1) // Remove error message
|
s.Pop(1) // Remove error message
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -123,10 +120,7 @@ func (s *State) RunBytecode() error {
|
|||||||
func (s *State) RunBytecodeWithResults(nresults int) error {
|
func (s *State) RunBytecodeWithResults(nresults int) error {
|
||||||
status := C.lua_pcall(s.L, 0, C.int(nresults), 0)
|
status := C.lua_pcall(s.L, 0, C.int(nresults), 0)
|
||||||
if status != 0 {
|
if status != 0 {
|
||||||
err := &LuaError{
|
err := s.CreateLuaError(int(status), fmt.Sprintf("RunBytecode(nresults=%d)", nresults))
|
||||||
Code: int(status),
|
|
||||||
Message: s.ToString(-1),
|
|
||||||
}
|
|
||||||
s.Pop(1) // Remove error message
|
s.Pop(1) // Remove error message
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -152,10 +146,7 @@ func (s *State) LoadAndRunBytecode(bytecode []byte, name string) error {
|
|||||||
)
|
)
|
||||||
|
|
||||||
if status != 0 {
|
if status != 0 {
|
||||||
err := &LuaError{
|
err := s.CreateLuaError(int(status), fmt.Sprintf("LoadAndRunBytecode(%s)", name))
|
||||||
Code: int(status),
|
|
||||||
Message: s.ToString(-1),
|
|
||||||
}
|
|
||||||
s.Pop(1) // Remove error message
|
s.Pop(1) // Remove error message
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -182,10 +173,7 @@ func (s *State) LoadAndRunBytecodeWithResults(bytecode []byte, name string, nres
|
|||||||
)
|
)
|
||||||
|
|
||||||
if status != 0 {
|
if status != 0 {
|
||||||
err := &LuaError{
|
err := s.CreateLuaError(int(status), fmt.Sprintf("LoadAndRunBytecodeWithResults(%s, nresults=%d)", name, nresults))
|
||||||
Code: int(status),
|
|
||||||
Message: s.ToString(-1),
|
|
||||||
}
|
|
||||||
s.Pop(1) // Remove error message
|
s.Pop(1) // Remove error message
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
82
stack.go
82
stack.go
@ -5,16 +5,45 @@ package luajit
|
|||||||
#include <lauxlib.h>
|
#include <lauxlib.h>
|
||||||
*/
|
*/
|
||||||
import "C"
|
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 {
|
type LuaError struct {
|
||||||
Code int
|
Code int
|
||||||
Message string
|
Message string
|
||||||
|
File string
|
||||||
|
Line int
|
||||||
|
StackTrace string
|
||||||
|
Context string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *LuaError) Error() 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
|
// Stack management constants from lua.h
|
||||||
@ -45,3 +74,50 @@ func (s *State) GetStackTrace() string {
|
|||||||
|
|
||||||
return trace
|
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)
|
status := C.luaL_loadstring(s.L, ccode)
|
||||||
if status != 0 {
|
if status != 0 {
|
||||||
err := &LuaError{
|
err := s.CreateLuaError(int(status), "LoadString")
|
||||||
Code: int(status),
|
|
||||||
Message: s.ToString(-1),
|
|
||||||
}
|
|
||||||
s.Pop(1) // Remove error message
|
s.Pop(1) // Remove error message
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -359,10 +356,7 @@ func (s *State) LoadFile(filename string) error {
|
|||||||
|
|
||||||
status := C.luaL_loadfile(s.L, cfilename)
|
status := C.luaL_loadfile(s.L, cfilename)
|
||||||
if status != 0 {
|
if status != 0 {
|
||||||
err := &LuaError{
|
err := s.CreateLuaError(int(status), fmt.Sprintf("LoadFile(%s)", filename))
|
||||||
Code: int(status),
|
|
||||||
Message: s.ToString(-1),
|
|
||||||
}
|
|
||||||
s.Pop(1) // Remove error message
|
s.Pop(1) // Remove error message
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -373,10 +367,7 @@ func (s *State) LoadFile(filename string) error {
|
|||||||
func (s *State) Call(nargs, nresults int) error {
|
func (s *State) Call(nargs, nresults int) error {
|
||||||
status := C.lua_pcall(s.L, C.int(nargs), C.int(nresults), 0)
|
status := C.lua_pcall(s.L, C.int(nargs), C.int(nresults), 0)
|
||||||
if status != 0 {
|
if status != 0 {
|
||||||
err := &LuaError{
|
err := s.CreateLuaError(int(status), fmt.Sprintf("Call(%d,%d)", nargs, nresults))
|
||||||
Code: int(status),
|
|
||||||
Message: s.ToString(-1),
|
|
||||||
}
|
|
||||||
s.Pop(1) // Remove error message
|
s.Pop(1) // Remove error message
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -390,10 +381,7 @@ func (s *State) DoString(code string) error {
|
|||||||
|
|
||||||
status := C.do_string(s.L, ccode)
|
status := C.do_string(s.L, ccode)
|
||||||
if status != 0 {
|
if status != 0 {
|
||||||
err := &LuaError{
|
err := s.CreateLuaError(int(status), "DoString")
|
||||||
Code: int(status),
|
|
||||||
Message: s.ToString(-1),
|
|
||||||
}
|
|
||||||
s.Pop(1) // Remove error message
|
s.Pop(1) // Remove error message
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -407,10 +395,7 @@ func (s *State) DoFile(filename string) error {
|
|||||||
|
|
||||||
status := C.do_file(s.L, cfilename)
|
status := C.do_file(s.L, cfilename)
|
||||||
if status != 0 {
|
if status != 0 {
|
||||||
err := &LuaError{
|
err := s.CreateLuaError(int(status), fmt.Sprintf("DoFile(%s)", filename))
|
||||||
Code: int(status),
|
|
||||||
Message: s.ToString(-1),
|
|
||||||
}
|
|
||||||
s.Pop(1) // Remove error message
|
s.Pop(1) // Remove error message
|
||||||
return err
|
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
|
status := C.execute_with_results(s.L, ccode, 1) // store_results=true
|
||||||
if status != 0 {
|
if status != 0 {
|
||||||
err := &LuaError{
|
err := s.CreateLuaError(int(status), "Execute")
|
||||||
Code: int(status),
|
|
||||||
Message: s.ToString(-1),
|
|
||||||
}
|
|
||||||
s.Pop(1) // Remove error message
|
s.Pop(1) // Remove error message
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user