ReviewOS

also looking at this

craft-native/craft

fix(ios): preserve specific protocol errors during dispatch

#303
Merged glennmichael123 wants to merge codex/preserve-native-bridge-errors into main
3 files +51 -11
packages/zig/src/ios_dispatch.zigmodified+29-0
Changes to packages/zig/src/ios_dispatch.zig
@@ -764,6 +764,10 @@ test "with no host shim present, the hand-off declines rather than failing" {
764764}
765765
766766test "a handler error reaches the page as something the protocol can say" {
767 inline for (@typeInfo(bridge_error.BridgeError).error_set.error_names.?) |name| {
768 const protocol_error = @field(bridge_error.BridgeError, name);
769 try testing.expectEqual(protocol_error, asBridgeError(protocol_error));
770 }
767771 // A handler's error set is wider than BridgeError. Whatever it raises still
768772 // has to arrive as an error code, because the alternative is a handler that
769773 // fails silently and leaves the caller on a promise that never settles.
@@ -790,6 +794,31 @@ test "a handler error reaches the page as something the protocol can say" {
790794 );
791795}
792796
797test "share without a webview keeps its specific error in the correlated reply" {
798 if (!builtin.target.os.tag.isDarwin()) return error.SkipZigTest;
799 const saved = getWebView();
800 defer setWebView(saved);
801 setWebView(null);
802
803 var system = bridge_mobile_system.SystemBridge.init(testing.allocator);
804 defer system.deinit();
805 system.handleMessage("share", "{\"text\":\"fixture\"}") catch |err| {
806 const narrowed = asBridgeError(err);
807 try testing.expectEqual(bridge_error.BridgeError.WebViewHandleNotSet, narrowed);
808 var context = bridge_error.ErrorContext.init(narrowed, "share", bridge_error.errorMessage(narrowed));
809 context.request_id = 71;
810 const json = try context.toJSON(testing.allocator);
811 defer testing.allocator.free(json);
812 const parsed = try std.json.parseFromSlice(std.json.Value, testing.allocator, json, .{});
813 defer parsed.deinit();
814 try testing.expectEqualStrings("WEBVIEW_HANDLE_NOT_SET", parsed.value.object.get("code").?.string);
815 try testing.expectEqualStrings("share", parsed.value.object.get("action").?.string);
816 try testing.expectEqual(@as(i64, 71), parsed.value.object.get("id").?.integer);
817 return;
818 };
819 return error.ShareSucceededWithoutWebView;
820}
821
793822test "a request id survives the trip out to the host and back" {
794823 // The shim may answer asynchronously, by which point the dispatch frame is
795824 // gone and `request_context.current()` is empty. The id is therefore read