Open thauschildt opened 8 months ago
Hey, I made a custom solution that works for my purposes, but I'm not making a pull request because I dont know if it covers everything / works generally
Replaced _runLuaClosure
with
void _runLuaClosure() {
try {
for (;;) {
int i = fetch();
OpCode opCode = Instruction.getOpCode(i);
opCode.action!.call(i, this);
if (opCode.name == "RETURN") {
break;
}
}
} on LuaClosureException catch (_) {
rethrow;
} catch (exception) {
// When a DART function is called by lua, then we want to use the PREV lua stack, as this one is a fake
// one which does not contain proto source info. The easiest way to do this is if the closure proto is null, get the previous one.
final targetStack = _stack?.closure?.proto == null ? _stack?.prev : _stack;
if(targetStack == null){
rethrow;
}
// Get this kind of stack trace only if source data is available.
final prototype = targetStack.closure?.proto;
if (prototype == null ||
prototype.source == null ||
prototype.lineDefined == null ||
prototype.lastLineDefined == null) {
rethrow;
}
throw LuaClosureException.fromPrototype(exception, prototype, targetStack.pc);
}
}
You can omit the lineDefined
and lastLineDefined
checks, I guess. They signify the start and end lines of the current closure. Originally I had the exception class get that entire code block, but now I only have the exception line and a few after and few before.
Implement an exception class. You can change the line range for more than -3/3, right now its hard coded.
class LuaClosureException { LuaClosureException( {required this.base, required this.exceptionSrc, required this.exceptionLine});
Object base; String exceptionSrc; int exceptionLine;
factory LuaClosureException.fromPrototype( Object baseException, Prototype proto, int luaPc) { final lineNumber = proto.lineInfo[luaPc]; final source = _getLinesRange( proto.source!, lineNumber - 3, lineNumber + 3, lineNumber);
return LuaClosureException(
base: baseException, exceptionSrc: source, exceptionLine: lineNumber);
}
@override String toString() { return "Unhandled LUA exception in line $exceptionLine:\n$exceptionSrc"; }
// Helper string function static String _getLinesRange( String input, int startLine, int endLine, int targetLine) { // Counter for the current line number int currentLine = 1;
// StringBuffer to build the result efficiently
StringBuffer result = StringBuffer();
// Variables to track line start and whether we are within the desired range
bool inRange = false;
// Iterate over each character in the string
for (int i = 0; i < input.length; i++) {
// Check if we are starting a new line
if (currentLine == startLine) {
inRange = true; // Start appending lines to the result
}
// Append the current character if it's within the range
if (inRange) {
result.write(input[i]);
}
// Check for newline characters to increment the line count
if (input[i] == '\n') {
if (inRange && currentLine >= endLine) {
break; // Stop if the end line has been reached
}
if (currentLine == targetLine - 1) {
result.write("==>");
}
currentLine++;
}
}
return result.toString();
} }
Hope this helps :)
Is it possible to get the line number in which a runtime error occurs?
If I run the code:
only the error message "Exception: not a function" is thrown.
For debugging larger scripts, it would be nice if the line number, in which the error occured, would be shown.