Skip to content

Commit

Permalink
add location to lua runtime exceptions where available
Browse files Browse the repository at this point in the history
the tests needed wholesale changes because of the scala stringmatcher for error messages being a bit too clever in matching

fixes mjanicek/rembulan#8
  • Loading branch information
kroepke committed Jun 1, 2017
1 parent f2cfff5 commit db23b05
Show file tree
Hide file tree
Showing 13 changed files with 313 additions and 298 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public class SuffixingClassNameTranslator implements ClassNameTranslator {
private final String base;

public SuffixingClassNameTranslator(String base) {
this.base = Objects.requireNonNull(base);
this.base = "rembulan_dynamic." + Objects.requireNonNull(base);
}

@Override
Expand Down
1 change: 1 addition & 0 deletions rembulan-parent/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
<encoding>UTF-8</encoding>
<rembulan.version>0.1-SNAPSHOT</rembulan.version>
</properties>

<distributionManagement>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public LuaRuntimeException(Throwable cause) {
*/
@Override
public String getMessage() {
return Conversions.toHumanReadableString(getErrorObject()).toString();
return getErrorLocation() + Conversions.toHumanReadableString(getErrorObject()).toString();
}

/**
Expand All @@ -79,4 +79,18 @@ public Object getErrorObject() {
}
}

/**
* Returns the closest location in the Lua code when this exception was triggered.
*
* @return the location of this error in the Lua code, @{code file:line} or @{code unknown:-1} if it could not be determined
*/
public String getErrorLocation() {
for (StackTraceElement stackTraceElement : getStackTrace()) {
if (stackTraceElement.getClassName().startsWith("rembulan_dynamic")) {
return stackTraceElement.getFileName() + ":" + stackTraceElement.getLineNumber() + ": ";
}
}
return "";
}

}
6 changes: 3 additions & 3 deletions rembulan-tests/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -49,19 +49,19 @@
<dependency>
<groupId>net.sandius.rembulan</groupId>
<artifactId>rembulan-runtime</artifactId>
<version>${project.parent.version}</version>
<version>${rembulan.version}</version>
</dependency>

<dependency>
<groupId>net.sandius.rembulan</groupId>
<artifactId>rembulan-compiler</artifactId>
<version>${project.parent.version}</version>
<version>${rembulan.version}</version>
</dependency>

<dependency>
<groupId>net.sandius.rembulan</groupId>
<artifactId>rembulan-stdlib</artifactId>
<version>${project.parent.version}</version>
<version>${rembulan.version}</version>
</dependency>

<dependency>
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ object BasicLibFragments extends FragmentBundle with FragmentExpectations with O
program ("return type(type)") succeedsWith "function"
program ("return type({})") succeedsWith "table"

program ("return type()") failsWith "bad argument #1 to 'type' (value expected)"
program ("return type()") failsWith ""<<"bad argument #1 to 'type' (value expected)"

}

Expand Down Expand Up @@ -84,7 +84,7 @@ object BasicLibFragments extends FragmentBundle with FragmentExpectations with O
program ("return tostring(tostring)") succeedsWith (stringStartingWith("function: "))
program ("return tostring({})") succeedsWith (stringStartingWith("table: "))

program ("return tostring()") failsWith "bad argument #1 to 'tostring' (value expected)"
program ("return tostring()") failsWith ""<<"bad argument #1 to 'tostring' (value expected)"

}

Expand All @@ -105,14 +105,14 @@ object BasicLibFragments extends FragmentBundle with FragmentExpectations with O
program ("return tonumber(\"3.0\")") succeedsWith 3.0
program ("return tonumber({})") succeedsWith null

program ("tonumber(1, \"x\")") failsWith "bad argument #2 to 'tonumber' (number expected, got string)"
program ("tonumber(1, \"x\")") failsWith ""<<"bad argument #2 to 'tonumber' (number expected, got string)"

program ("tonumber(\"1\", 1)") failsWith "bad argument #2 to 'tonumber' (base out of range)"
program ("tonumber(\"1\", 37)") failsWith "bad argument #2 to 'tonumber' (base out of range)"
program ("tonumber(\"1\", 1)") failsWith ""<<"bad argument #2 to 'tonumber' (base out of range)"
program ("tonumber(\"1\", 37)") failsWith ""<<"bad argument #2 to 'tonumber' (base out of range)"

program ("tonumber(1, 1)") failsWith "bad argument #1 to 'tonumber' (string expected, got number)"
program ("tonumber(nil, 10)") failsWith "bad argument #1 to 'tonumber' (string expected, got nil)"
program ("tonumber(nil, 1)") failsWith "bad argument #1 to 'tonumber' (string expected, got nil)"
program ("tonumber(1, 1)") failsWith ""<<"bad argument #1 to 'tonumber' (string expected, got number)"
program ("tonumber(nil, 10)") failsWith ""<<"bad argument #1 to 'tonumber' (string expected, got nil)"
program ("tonumber(nil, 1)") failsWith ""<<"bad argument #1 to 'tonumber' (string expected, got nil)"

program ("return tonumber(\"-AbCd\", 14)") succeedsWith -29777
program ("return tonumber(\"+Hello\", 36)") succeedsWith 29234652
Expand All @@ -122,11 +122,11 @@ object BasicLibFragments extends FragmentBundle with FragmentExpectations with O
program ("return tonumber(\"99\", 9)") succeedsWith null
program ("return tonumber(\"zzz\", 36)") succeedsWith 46655

program ("return tonumber(1 / 0, 36)") failsWith "bad argument #1 to 'tonumber' (string expected, got number)"
program ("return tonumber(0 / 0, 36)") failsWith "bad argument #1 to 'tonumber' (string expected, got number)"
program ("return tonumber(0.2, 10)") failsWith "bad argument #1 to 'tonumber' (string expected, got number)"
program ("return tonumber(1 / 0, 36)") failsWith ""<<"bad argument #1 to 'tonumber' (string expected, got number)"
program ("return tonumber(0 / 0, 36)") failsWith ""<<"bad argument #1 to 'tonumber' (string expected, got number)"
program ("return tonumber(0.2, 10)") failsWith ""<<"bad argument #1 to 'tonumber' (string expected, got number)"

program ("return tonumber()") failsWith "bad argument #1 to 'tonumber' (value expected)"
program ("return tonumber()") failsWith ""<<"bad argument #1 to 'tonumber' (value expected)"

}

Expand All @@ -137,15 +137,15 @@ object BasicLibFragments extends FragmentBundle with FragmentExpectations with O
program ("return getmetatable(0)") succeedsWith null
program ("return getmetatable(\"hurray\")") succeedsWith null // defined by the string library

program ("getmetatable()") failsWith "bad argument #1 to 'getmetatable' (value expected)"
program ("getmetatable()") failsWith ""<<"bad argument #1 to 'getmetatable' (value expected)"

}

about ("setmetatable") {

program ("setmetatable(0, nil)") failsWith "bad argument #1 to 'setmetatable' (table expected, got number)"
program ("setmetatable({}, 0)") failsWith "bad argument #2 to 'setmetatable' (nil or table expected)"
program ("setmetatable({})") failsWith "bad argument #2 to 'setmetatable' (nil or table expected)"
program ("setmetatable(0, nil)") failsWith ""<<"bad argument #1 to 'setmetatable' (table expected, got number)"
program ("setmetatable({}, 0)") failsWith ""<<"bad argument #2 to 'setmetatable' (nil or table expected)"
program ("setmetatable({})") failsWith ""<<"bad argument #2 to 'setmetatable' (nil or table expected)"

val SetMetatableReturnsItsFirstArgument = fragment("setmetatable returns its first argument") {
"""local x = {}
Expand Down Expand Up @@ -185,7 +185,7 @@ object BasicLibFragments extends FragmentBundle with FragmentExpectations with O
program ("return pcall(pcall)") succeedsWith (false, "bad argument #1 to 'pcall' (value expected)")
program ("return pcall(pcall, pcall, pcall)") succeedsWith (true, true, false, "bad argument #1 to 'pcall' (value expected)")

program ("pcall()") failsWith "bad argument #1 to 'pcall' (value expected)"
program ("pcall()") failsWith ""<<"bad argument #1 to 'pcall' (value expected)"

val PCallHonoursTheCallMetamethod = fragment ("pcall honours the __call metamethod") {
"""function callable()
Expand Down Expand Up @@ -222,10 +222,10 @@ object BasicLibFragments extends FragmentBundle with FragmentExpectations with O

about ("xpcall") {

program ("xpcall()") failsWith "bad argument #2 to 'xpcall' (function expected, got no value)"
program ("return xpcall(nil)") failsWith "bad argument #2 to 'xpcall' (function expected, got no value)"
program ("return xpcall(function() end)") failsWith "bad argument #2 to 'xpcall' (function expected, got no value)"
program ("return xpcall(nil, nil)") failsWith "bad argument #2 to 'xpcall' (function expected, got nil)"
program ("xpcall()") failsWith ""<<"bad argument #2 to 'xpcall' (function expected, got no value)"
program ("return xpcall(nil)") failsWith ""<<"bad argument #2 to 'xpcall' (function expected, got no value)"
program ("return xpcall(function() end)") failsWith ""<<"bad argument #2 to 'xpcall' (function expected, got no value)"
program ("return xpcall(nil, nil)") failsWith ""<<"bad argument #2 to 'xpcall' (function expected, got nil)"

program ("return xpcall(nil, function(...) return ... end)") succeedsWith (false, "attempt to call a nil value")

Expand Down Expand Up @@ -258,20 +258,20 @@ object BasicLibFragments extends FragmentBundle with FragmentExpectations with O
}

about ("assert") {
program ("assert(nil)") failsWith "assertion failed!"
program ("assert(false, 'boom')") failsWith "boom"
program ("assert(nil)") failsWith ""<<"assertion failed!"
program ("assert(false, 'boom')") failsWith ""<<"boom"

program ("return assert(true)") succeedsWith true
program ("return assert(1, false, 'x')") succeedsWith (1, false, "x")

program ("assert()") failsWith "bad argument #1 to 'assert' (value expected)"
program ("assert()") failsWith ""<<"bad argument #1 to 'assert' (value expected)"

program ("assert(pcall(error, 'boom'))") failsWith "boom"
program ("assert(pcall(error, 'boom'))") failsWith ""<<"boom"
}

about ("rawequal") {
program ("return rawequal()") failsWith "bad argument #1 to 'rawequal' (value expected)"
program ("return rawequal(nil)") failsWith "bad argument #2 to 'rawequal' (value expected)"
program ("return rawequal()") failsWith ""<<"bad argument #1 to 'rawequal' (value expected)"
program ("return rawequal(nil)") failsWith ""<<"bad argument #2 to 'rawequal' (value expected)"

program ("return rawequal(nil, nil)") succeedsWith true
program ("return rawequal(0, 0)") succeedsWith true
Expand All @@ -281,9 +281,9 @@ object BasicLibFragments extends FragmentBundle with FragmentExpectations with O
}

about ("rawget") {
program ("rawget()") failsWith "bad argument #1 to 'rawget' (table expected, got no value)"
program ("rawget(nil)") failsWith "bad argument #1 to 'rawget' (table expected, got nil)"
program ("rawget('x')") failsWith "bad argument #1 to 'rawget' (table expected, got string)"
program ("rawget()") failsWith ""<<"bad argument #1 to 'rawget' (table expected, got no value)"
program ("rawget(nil)") failsWith ""<<"bad argument #1 to 'rawget' (table expected, got nil)"
program ("rawget('x')") failsWith ""<<"bad argument #1 to 'rawget' (table expected, got string)"

program (
"""x = {}
Expand All @@ -295,20 +295,20 @@ object BasicLibFragments extends FragmentBundle with FragmentExpectations with O
}

about ("rawset") {
program ("rawset()") failsWith "bad argument #1 to 'rawset' (table expected, got no value)"
program ("rawset(nil)") failsWith "bad argument #1 to 'rawset' (table expected, got nil)"
program ("rawset('x')") failsWith "bad argument #1 to 'rawset' (table expected, got string)"
program ("rawset()") failsWith ""<<"bad argument #1 to 'rawset' (table expected, got no value)"
program ("rawset(nil)") failsWith ""<<"bad argument #1 to 'rawset' (table expected, got nil)"
program ("rawset('x')") failsWith ""<<"bad argument #1 to 'rawset' (table expected, got string)"

program ("rawset({}, nil)") failsWith "bad argument #3 to 'rawset' (value expected)"
program ("rawset({}, nil)") failsWith ""<<"bad argument #3 to 'rawset' (value expected)"

program (
"""x = {}
|rawset(x, 'hello', 'world')
|return x.hello
""") succeedsWith "world"

program ("rawset({}, nil, 1)") failsWith "table index is nil"
program ("rawset({}, 0 / 0, 1)") failsWith "table index is NaN"
program ("rawset({}, nil, 1)") failsWith ""<<"table index is nil"
program ("rawset({}, 0 / 0, 1)") failsWith ""<<"table index is NaN"

program (
"""x = {}
Expand All @@ -321,8 +321,8 @@ object BasicLibFragments extends FragmentBundle with FragmentExpectations with O

about ("rawlen") {

program ("rawlen()") failsWith "bad argument #1 to 'rawlen' (table or string expected)"
program ("rawlen(1)") failsWith "bad argument #1 to 'rawlen' (table or string expected)"
program ("rawlen()") failsWith ""<<"bad argument #1 to 'rawlen' (table or string expected)"
program ("rawlen(1)") failsWith ""<<"bad argument #1 to 'rawlen' (table or string expected)"

program ("return rawlen('x')") succeedsWith 1
program ("return rawlen({'x', 1, true})") succeedsWith 3
Expand All @@ -331,11 +331,11 @@ object BasicLibFragments extends FragmentBundle with FragmentExpectations with O
}

about ("select") {
program ("select()") failsWith "bad argument #1 to 'select' (number expected, got no value)"
program ("select()") failsWith ""<<"bad argument #1 to 'select' (number expected, got no value)"

program ("select('x')") failsWith "bad argument #1 to 'select' (number expected, got string)"
program ("select(' #')") failsWith "bad argument #1 to 'select' (number expected, got string)"
program ("select(' # ')") failsWith "bad argument #1 to 'select' (number expected, got string)"
program ("select('x')") failsWith ""<<"bad argument #1 to 'select' (number expected, got string)"
program ("select(' #')") failsWith ""<<"bad argument #1 to 'select' (number expected, got string)"
program ("select(' # ')") failsWith ""<<"bad argument #1 to 'select' (number expected, got string)"

program ("return select('#')") succeedsWith 0
program ("return select('#', nil)") succeedsWith 1
Expand All @@ -345,10 +345,10 @@ object BasicLibFragments extends FragmentBundle with FragmentExpectations with O
program ("return select('-1', true, false)") succeedsWith (false)

program ("return select(7, true, false)") succeedsWith ()
program ("select(0, true, false)") failsWith "bad argument #1 to 'select' (index out of range)"
program ("select(-3, true, false)") failsWith "bad argument #1 to 'select' (index out of range)"
program ("select(0, true, false)") failsWith ""<<"bad argument #1 to 'select' (index out of range)"
program ("select(-3, true, false)") failsWith ""<<"bad argument #1 to 'select' (index out of range)"

program ("select(1.5, true, false)") failsWith "bad argument #1 to 'select' (number has no integer representation)"
program ("select(1.5, true, false)") failsWith ""<<"bad argument #1 to 'select' (number has no integer representation)"

program ("return select(1, 1, 2, 3, 4, 5)") succeedsWith (1, 2, 3, 4, 5)
program ("return select(-1, 1, 2, 3, 4, 5)") succeedsWith (5)
Expand All @@ -360,9 +360,9 @@ object BasicLibFragments extends FragmentBundle with FragmentExpectations with O

about ("load") {

program ("load()") failsWith "bad argument #1 to 'load' (function expected, got no value)"
program ("load({})") failsWith "bad argument #1 to 'load' (function expected, got table)"
program ("load(nil)") failsWith "bad argument #1 to 'load' (function expected, got nil)"
program ("load()") failsWith ""<<"bad argument #1 to 'load' (function expected, got no value)"
program ("load({})") failsWith ""<<"bad argument #1 to 'load' (function expected, got table)"
program ("load(nil)") failsWith ""<<"bad argument #1 to 'load' (function expected, got nil)"

program ("return load(42)") succeedsWith (null, classOf[String])
program ("return load(42, 42, 42)") succeedsWith (null, "attempt to load a text chunk (mode is '42')")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ object CoroutineLibFragments extends FragmentBundle with FragmentExpectations {
|assert(false)
"""
}
ResumeReturnsControlToCallerOnExit1 in CoroContext failsWith (classOf[AssertionFailedException], "assertion failed!")
ResumeReturnsControlToCallerOnExit1 in CoroContext failsWith (classOf[AssertionFailedException], ""<<"assertion failed!")

val ResumeReturnsControlToCallerOnExit2 = fragment ("ResumeReturnsControlToCallerOnExit2") {
"""return coroutine.resume(coroutine.create(function() end))
Expand Down Expand Up @@ -141,15 +141,15 @@ object CoroutineLibFragments extends FragmentBundle with FragmentExpectations {
|return
"""
}
YieldFromOutsideCoroutine in CoroContext failsWith (classOf[IllegalCoroutineStateException], "attempt to yield from outside a coroutine")
YieldFromOutsideCoroutine in CoroContext failsWith (classOf[IllegalCoroutineStateException], ""<<"attempt to yield from outside a coroutine")

val WrapNormalFunctionCannotBeCalledTwice = fragment ("WrapNormalFunctionCannotBeCalledTwice") {
"""local f = coroutine.wrap(function() end)
|f()
|f()
"""
}
WrapNormalFunctionCannotBeCalledTwice in CoroContext failsWith (classOf[IllegalCoroutineStateException], "cannot resume dead coroutine")
WrapNormalFunctionCannotBeCalledTwice in CoroContext failsWith (classOf[IllegalCoroutineStateException], ""<<"cannot resume dead coroutine")

val WrappedCoroutineRunning = fragment ("WrappedCoroutineRunning") {
"""return coroutine.wrap(coroutine.running)()
Expand Down
Loading

0 comments on commit db23b05

Please sign in to comment.