Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consistent, structured returned error value #46

Closed
mholt opened this issue Sep 4, 2015 · 3 comments
Closed

Consistent, structured returned error value #46

mholt opened this issue Sep 4, 2015 · 3 comments

Comments

@mholt
Copy link

mholt commented Sep 4, 2015

Hi. Really loving gopher-lua so far and excited to keep using it! Thanks for making it.

I'm struggling with error handling at the moment. Basically, I'd like to do my own error reporting. The error returned from the Do functions could be a concrete type that has structured access to the line and column number and error message.

if err := L.DoString(luaCode); err != nil {
    // access to line and column number here would be awesome!
}

If you're too busy, I'm willing to make the changes but am not sure the best way to go about it. The DoString function could still return error type, but the underlying type (after a type assertion) would ideally expose the line, column numbers as well as the error message and maybe error type (syntax, etc.). Right now the error is like this:

&lua.ApiError{Type:0, Object:"<string> line:3(column:5) near 'if':   syntax error\n", StackTrace:""}

But I'd like to be able to do this:

if err := L.DoString(luaCode); err != nil {
    luaErr := err.(lua.Error) // or whatever
    fmt.Println("Error type:", luaErr.Type)
    fmt.Println("Line:", luaErr.Line)
    fmt.Println("Col:", luaErr.Column)
    fmt.Println("Message:", luaErr.Message)
}

What do you think?

@mholt mholt changed the title Consistent, structured error type Consistent, structured returned error value Sep 4, 2015
@yuin
Copy link
Owner

yuin commented Sep 5, 2015

I'm glad to hear that.
Hmm, this functionality is not defined in Lua5.1, so I'll see if there is a neat way around the issue.

@yuin
Copy link
Owner

yuin commented Sep 5, 2015

I've added a Cause attribute to the ApiError. Now you can get the detailed error information in response to Type value:

You will want to write utilities like the following:

package main

import (
    "github.com/yuin/gopher-lua"
    "github.com/yuin/gopher-lua/parse"
)

func myDoString(L *lua.LState, source string) error {
    fn, err := L.LoadString(source)
    if err != nil {
        if lerr := err.(*lua.ApiError); lerr != nil {
            switch cause := lerr.Cause.(type) {
            case *parse.Error:
                println("Syntax error:", cause.Error())
                println("Line: ", cause.Pos.Line)
                println("Column: ", cause.Pos.Column)
            case *lua.CompileError:
                println("Compile error:", cause.Error())
                println("Line: ", cause.Line)
            default:
                println(lerr.Error())
            }
        }
        return err
    }

    L.Push(fn)
    return L.PCall(0, lua.MultRet, L.NewFunction(func(L *lua.LState) int {
        obj := L.Get(1)
        dbg, _ := L.GetStack(1)
        L.GetInfo("Slunf", dbg, lua.LNil)
        println("Runtime error:", obj.String())
        println("Line:", dbg.CurrentLine)
        return 1 // retuens the original object
    }))
}

func main() {
    L := lua.NewState()
    myDoString(L, `
      print(1)
      print(2)
      pint(3)
      print(4)
      print(5)
    `)
}

@mholt
Copy link
Author

mholt commented Sep 5, 2015

This is great! Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants