I am working on a js library which focuses on error handling. A part of the lib is a stack parser which I'd like to work in most of the environments.
The hard part that there is no standard way to represent the stack, so every environment has its own stack string format. The variable parts are message, type and frames. A frame usually consists of called function, file, line, column.
In some of the environments there are additional variable regions on the string, in others some of the variables are not present. I can run automated tests only in the 5 most common environments, but there are a lot more environments I'd like the parser to work in.
- My goal is to write an adaptive parser, which learns the stack string format of the actual environment on the fly, and after that it can parse the stack of any exception of that environment.
I already have a plan how to solve this in the traditional way, but I am curious, is there any machine learning tool (probably in the topic of unsupervised learning) I could use to solve this problem?
According to the comments I need to clarify the terms "stack string format" and "stack parser". I think it is better to write 2 examples from different environments:
A.)
example stack string:
Statement on line 44: Type mismatch (usually a non-object value used where an object is required)
Backtrace:
Line 44 of linked script file://localhost/G:/js/stacktrace.js
this.undef();
Line 31 of linked script file://localhost/G:/js/stacktrace.js
ex = ex || this.createException();
Line 18 of linked script file://localhost/G:/js/stacktrace.js
var p = new printStackTrace.implementation(), result = p.run(ex);
Line 4 of inline#1 script in file://localhost/G:/js/test/functional/testcase1.html
printTrace(printStackTrace());
Line 7 of inline#1 script in file://localhost/G:/js/test/functional/testcase1.html
bar(n - 1);
Line 11 of inline#1 script in file://localhost/G:/js/test/functional/testcase1.html
bar(2);
Line 15 of inline#1 script in file://localhost/G:/js/test/functional/testcase1.html
foo();
stack string format (template):
Statement on line {frames[0].location.line}: {message}
Backtrace:
{foreach frames as frame}
Line {frame.location.line} of {frame.unknown[0]} {frame.location.path}
{frame.calledFunction}
{/foreach}
extracted information (json):
{
message: "Type mismatch (usually a non-object value used where an object is required)",
frames: [
{
calledFunction: "this.undef();",
location: {
path: "file://localhost/G:/js/stacktrace.js",
line: 44
},
unknown: ["linked script"]
},
{
calledFunction: "ex = ex || this.createException();",
location: {
path: "file://localhost/G:/js/stacktrace.js",
line: 31
},
unknown: ["inline#1 script in"]
},
...
]
}
B.)
example stack string:
ReferenceError: x is not defined
at repl:1:5
at REPLServer.self.eval (repl.js:110:21)
at repl.js:249:20
at REPLServer.self.eval (repl.js:122:7)
at Interface.<anonymous> (repl.js:239:12)
at Interface.EventEmitter.emit (events.js:95:17)
at Interface._onLine (readline.js:202:10)
at Interface._line (readline.js:531:8)
at Interface._ttyWrite (readline.js:760:14)
at ReadStream.onkeypress (readline.js:99:10)
stack string format (template):
{type}: {message}
{foreach frames as frame}
{if frame.calledFunction is undefined}
at {frame.location.path}:{frame.location.line}:{frame.location.column}
{else}
at {frame.calledFunction} ({frame.location.path}:{frame.location.line}:{frame.location.column})
{/if}
{/foreach}
extracted information (json):
{
message: "x is not defined",
type: "ReferenceError",
frames: [
{
location: {
path: "repl",
line: 1,
column: 5
}
},
{
calledFunction: "REPLServer.self.eval",
location: {
path: "repl.js",
line: 110,
column: 21
}
},
...
]
}
The parser should process the stack strings and return the extracted information. The stack string format and the variables are environment dependent, the library should figure out on the fly how to parse the stack strings of the actual environment.
I can probe the actual environment by throwing exceptions with well known stacks and check the differences of the stack strings. For example if I add a whitespace indentation to the line that throws the exception, then the column and probably the called function variables will change. If I detect a number change somewhere, then I can be sure that we are talking about the column variable. I can add line breaks too, which will cause line number change and so on...
I can probe for every important variables, but I cannot be sure that the actual string does not contain additional unknown variables and I cannot be sure that all of the known variables will be added to it. For example the frame strings of the "A" example contain an unknown variable and do not contain the column variable, while the frame strings of the "B" example do not always contain the called function variable.