feat: add Fiber.try() method for catching errors across fiber boundaries

Implement a new `Fiber.try()` method that allows a calling fiber to catch runtime errors from a called fiber. When a fiber is invoked with `try()` instead of `call()`, any runtime error that occurs in the called fiber is returned as a string to the caller rather than terminating the program with a stack trace. The `callerIsTrying` flag on `ObjFiber` tracks this state, and the `runtimeError` function now checks this flag to redirect the error to the caller's stack. Also adds `Fiber.error` getter to retrieve the error string from a failed fiber, changes `Fiber.isDone` to return `true` for errored fibers, and migrates the fiber error field from a raw `char*` to an `ObjString*` for proper memory management. Includes comprehensive test cases for try behavior, re-entry prevention, and error state queries.
This commit is contained in:
Bob Nystrom
2014-10-15 13:36:42 +00:00
parent d4a858da43
commit d60068db56
13 changed files with 162 additions and 37 deletions
+7
View File
@@ -0,0 +1,7 @@
var fiber = new Fiber {
"s".unknown
}
IO.print(fiber.error) // expect: null
IO.print(fiber.try) // expect: String does not implement method 'unknown'.
IO.print(fiber.error) // expect: String does not implement method 'unknown'.
+6
View File
@@ -0,0 +1,6 @@
var fiber = new Fiber {
"s".unknown
}
fiber.try
IO.print(fiber.isDone) // expect: true
+10
View File
@@ -0,0 +1,10 @@
var fiber = new Fiber {
IO.print("before")
true.unknownMethod
IO.print("after")
}
IO.print(fiber.try)
// expect: before
// expect: Bool does not implement method 'unknownMethod'.
IO.print("after try") // expect: after try
+7
View File
@@ -0,0 +1,7 @@
var fiber
fiber = new Fiber {
fiber.try // expect runtime error: Fiber has already been called.
}
fiber.call
+12
View File
@@ -0,0 +1,12 @@
var a
var b
a = new Fiber {
b.try // expect runtime error: Fiber has already been called.
}
b = new Fiber {
a.call
}
b.call
+6
View File
@@ -0,0 +1,6 @@
var fiber = new Fiber {
IO.print("try")
}
fiber.try // expect: try
fiber.try // expect runtime error: Cannot try a finished fiber.
+8
View File
@@ -0,0 +1,8 @@
var fiber = new Fiber {
IO.print("fiber")
}
IO.print("before") // expect: before
IO.print(fiber.try) // expect: fiber
// expect: null
IO.print("after") // expect: after