Change fallible return type to Result union
diff --git a/src/exception.rs b/src/exception.rs
deleted file mode 100644
index 57ff552..0000000
--- a/src/exception.rs
+++ /dev/null
@@ -1,39 +0,0 @@
-use std::fmt::Display;
-use std::ptr;
-
-#[repr(C)]
-pub struct Error {
-    ptr: *const u8,
-    len: usize,
-}
-
-pub unsafe fn r#try<T, E>(ret: *mut T, result: Result<T, E>) -> Error
-where
-    E: Display,
-{
-    match result {
-        Ok(ok) => {
-            ptr::write(ret, ok);
-            Error {
-                ptr: ptr::null(),
-                len: 0,
-            }
-        }
-        Err(err) => to_c_string(err.to_string()),
-    }
-}
-
-unsafe fn to_c_string(msg: String) -> Error {
-    let mut msg = msg;
-    msg.as_mut_vec().push(b'\0');
-    let ptr = msg.as_ptr();
-    let len = msg.len();
-
-    extern "C" {
-        #[link_name = "cxxbridge02$error"]
-        fn error(ptr: *const u8, len: usize) -> *const u8;
-    }
-
-    let copy = error(ptr, len);
-    Error { ptr: copy, len }
-}
diff --git a/src/lib.rs b/src/lib.rs
index aa7e84f..b985e1d 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -354,10 +354,10 @@
 
 mod cxx_string;
 mod error;
-mod exception;
 mod gen;
 mod opaque;
 mod paths;
+mod result;
 mod rust_str;
 mod rust_string;
 mod syntax;
@@ -371,8 +371,8 @@
 // Not public API.
 #[doc(hidden)]
 pub mod private {
-    pub use crate::exception::{r#try, Error};
     pub use crate::opaque::Opaque;
+    pub use crate::result::{r#try, Result};
     pub use crate::rust_str::RustStr;
     pub use crate::rust_string::RustString;
     pub use crate::unique_ptr::UniquePtrTarget;
diff --git a/src/result.rs b/src/result.rs
new file mode 100644
index 0000000..6d04a2d
--- /dev/null
+++ b/src/result.rs
@@ -0,0 +1,43 @@
+use crate::rust_str::RustStr;
+use std::fmt::Display;
+use std::ptr;
+use std::result::Result as StdResult;
+use std::slice;
+use std::str;
+
+#[repr(C)]
+pub union Result {
+    err: RustStr,
+    ok: *const u8, // null
+}
+
+pub unsafe fn r#try<T, E>(ret: *mut T, result: StdResult<T, E>) -> Result
+where
+    E: Display,
+{
+    match result {
+        Ok(ok) => {
+            ptr::write(ret, ok);
+            Result { ok: ptr::null() }
+        }
+        Err(err) => to_c_error(err.to_string()),
+    }
+}
+
+unsafe fn to_c_error(msg: String) -> Result {
+    let mut msg = msg;
+    msg.as_mut_vec().push(b'\0');
+    let ptr = msg.as_ptr();
+    let len = msg.len();
+
+    extern "C" {
+        #[link_name = "cxxbridge02$error"]
+        fn error(ptr: *const u8, len: usize) -> *const u8;
+    }
+
+    let copy = error(ptr, len);
+    let slice = slice::from_raw_parts(copy, len);
+    let string = str::from_utf8_unchecked(slice);
+    let err = RustStr::from(string);
+    Result { err }
+}