diff --git a/doc/site/modules/core/fiber.markdown b/doc/site/modules/core/fiber.markdown index f869abbb..904c9a6b 100644 --- a/doc/site/modules/core/fiber.markdown +++ b/doc/site/modules/core/fiber.markdown @@ -174,6 +174,24 @@ System.print("Caught error: " + error) If the called fiber raises an error, it can no longer be used. +### **try**(value) +Tries to run the fiber. If a runtime error occurs +in the called fiber, the error is captured and is returned as a string. +If the fiber is being +started for the first time, and its function takes a parameter, `value` is +passed to it. + +
+var fiber = Fiber.new {|value|
+ value.badMethod
+}
+
+var error = fiber.try("just a string")
+System.print("Caught error: " + error)
+
+
+If the called fiber raises an error, it can no longer be used.
+
### **transfer**()
**TODO**
diff --git a/src/vm/wren_core.c b/src/vm/wren_core.c
index 0aaf8c29..033351fa 100644
--- a/src/vm/wren_core.c
+++ b/src/vm/wren_core.c
@@ -191,6 +191,15 @@ DEF_PRIMITIVE(fiber_try)
return false;
}
+DEF_PRIMITIVE(fiber_try1)
+{
+ runFiber(vm, AS_FIBER(args[0]), args, true, true, "try");
+
+ // If we're switching to a valid fiber to try, remember that we're trying it.
+ if (!wrenHasError(vm->fiber)) vm->fiber->state = FIBER_TRY;
+ return false;
+}
+
DEF_PRIMITIVE(fiber_yield)
{
ObjFiber* current = vm->fiber;
@@ -1235,6 +1244,7 @@ void wrenInitializeCore(WrenVM* vm)
PRIMITIVE(vm->fiberClass, "transfer(_)", fiber_transfer1);
PRIMITIVE(vm->fiberClass, "transferError(_)", fiber_transferError);
PRIMITIVE(vm->fiberClass, "try()", fiber_try);
+ PRIMITIVE(vm->fiberClass, "try(_)", fiber_try1);
vm->fnClass = AS_CLASS(wrenFindVariable(vm, coreModule, "Fn"));
PRIMITIVE(vm->fnClass->obj.classObj, "new(_)", fn_new);
diff --git a/test/core/fiber/try_value.wren b/test/core/fiber/try_value.wren
new file mode 100644
index 00000000..9416fece
--- /dev/null
+++ b/test/core/fiber/try_value.wren
@@ -0,0 +1,12 @@
+var fiber = Fiber.new {|v|
+ System.print("before")
+ System.print(v)
+ true.unknownMethod
+ System.print("after")
+}
+
+System.print(fiber.try("value"))
+// expect: before
+// expect: value
+// expect: Bool does not implement 'unknownMethod'.
+System.print("after try") // expect: after try
diff --git a/test/core/fiber/try_value_yield.wren b/test/core/fiber/try_value_yield.wren
new file mode 100644
index 00000000..4a44d05c
--- /dev/null
+++ b/test/core/fiber/try_value_yield.wren
@@ -0,0 +1,16 @@
+var fiber = Fiber.new {|v|
+ System.print("before")
+ System.print(v)
+ v = Fiber.yield()
+ System.print(v)
+ true.unknownMethod
+ System.print("after")
+}
+
+fiber.try("value1")
+// expect: before
+// expect: value1
+System.print(fiber.try("value2"))
+// expect: value2
+// expect: Bool does not implement 'unknownMethod'.
+System.print("after try") // expect: after try