sapling/eden/scm/lib/cpython-ext/Cargo.toml
Meyer Jacobs e3b86cf77d debug: introduce binding layer for propagating error metadata to Python
Summary:
Implements based Rust-Python binding layer for error metadata propagation.

We introduce a new type, `TaggedExceptionData`, which carries CommonMetadata and the original (without metadata) error message for a Rust Anyhow error. This class is passed to RustError and can be accessed in Python (somewhat awkwardly) via indexing:
```
except error.RustError as e:
    fault = e.args[0].fault()
    typename = e.args[0].typename()
    message = e.args[0].message()
```
As far as I can tell, due to limitations in cpython-rs, this can't be made more ergonomic without introducing a Python shim around the Rust binding layer, which could adapt the cpython-rs classes to use whatever API we'd like.

Currently, anyhow errors that are not otherwise special-cased will be converted into RustError, with both the original error message and any attached metadata printed as shown below
```
  abort: intentional error for debugging with message 'intentional_error'
  error has type name taggederror::IntentionalError and fault None
```
We can of course re-raise the error if desired to maintain the previous behavior for handling a RustError.

If we'd like other, specialized Rust Python Exception types to carry metadata (such as `IndexedLogError`), we'll need to modify them to accept a `TaggedExceptionData` like `RustError`.

Renamed the "cause an error in pure rust command" function to `debugcauserusterror`, and instead used the name `debugthrowrustexception` for a command which causes an error in rust which is converted to a Python exception across the binding layer.

Introduced a simple integration test which exercises `debugthrowrustexception`.

Added a basic handler for RustError to scmutil.py

Reviewed By: DurhamG

Differential Revision: D22517796

fbshipit-source-id: 0409489243fe739a26958aad48f608890eb93aa0
2020-07-16 19:30:00 -07:00

24 lines
584 B
TOML

[package]
name = "cpython-ext"
version = "0.1.0"
edition = "2018"
[features]
default = ["python2"]
python2 = ["python27-sys", "cpython/python27-sys"]
python3 = ["python3-sys", "cpython/python3-sys"]
[dependencies]
anyhow = "1.0.20"
cpython = { version = "0.5", default-features = false }
encoding = { path = "../encoding" }
lazy_static = "1"
libc = "0.2"
parking_lot = "0.9"
python27-sys = { version = "0.5", optional = true }
python3-sys = { version = "0.5", optional = true }
serde = "1"
taggederror = { path = "../taggederror" }
thiserror = "1.0.5"
types = { path = "../types" }