-
Notifications
You must be signed in to change notification settings - Fork 43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enum support for TryIntoJs, structured errors from Result #155
Conversation
Hello again @mkawalec, thanks for the PR! I'll review it soon and get back with any comments! |
{ | ||
fn try_to_js(self, js_env: &JsEnv) -> Result<napi_value, NjError> { | ||
match self { | ||
Ok(val) => val.try_to_js(&js_env), | ||
Err(err) => Err(NjError::Other(err.to_string())), | ||
Err(err) => Err(NjError::Native(err.try_to_js(&js_env)?)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll have to add TryIntoJs
for NjError
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you able to do this? I'm running into this error when building the examples
error[E0599]: the method `try_to_js` exists for enum `Result<i32, NjError>`, but its trait bounds were not satisfied
--> function/src/lib.rs:15:1
|
15 | #[node_bindgen]
| ^^^^^^^^^^^^^^^ method cannot be called on `Result<i32, NjError>` due to unsatisfied trait bounds
|
::: /Users/nick/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/result.rs:241:1
|
241 | pub enum Result<T, E> {
| --------------------- doesn't satisfy `Result<i32, NjError>: TryIntoJs`
|
::: /Users/nick/infinyon/node-bindgen/nj-core/src/error.rs:12:1
|
12 | pub enum NjError {
| ---------------- doesn't satisfy `NjError: TryIntoJs`
|
= note: the following trait bounds were not satisfied:
`NjError: TryIntoJs`
which is required by `Result<i32, NjError>: TryIntoJs`
= note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error
For more information about this error, try `rustc --explain E0599`.
error: could not compile `nj-example-function`
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, not yet, I'll update the PR tomorrow.
rebase from master |
CHANGELOG.md
Outdated
@@ -3,6 +3,12 @@ | |||
## Unreleased | |||
### Improvements | |||
|
|||
## [4.5.0] - TBD |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
4.4.0
wasn't release, so we can merged into 4.5 release!
README.md
Outdated
assert.deepStrictEqual(addon.withUnit(), "UnitErrorType") | ||
``` | ||
|
||
Unnamed variants will be converted to lists, named to objects and unit variants to strings equal to their name in PascalCase. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The wording here is a bit confusing at first glance. How about
Tuple variants will be converted into lists, struct variants converted to objects, and unit variants converted into strings matching the variant's name in PascalCase.
rebase please |
To avoid breaking changes, it is possible add auto impl for TryIntoJs for string? |
@sehz so string-containing errors are converted to strings, but other kinds of errors keep their structure? I think there's a possible solution out there, I'll find one that isn't breaking. |
@sehz Unfortunately not, I'll keep on poking on this today, asking in case I don't find a non-breaking solution. |
@nicholastmosher idea on how to keep compatibility? If not we will do major semversion. That willl also give up opportunity to clean up other API as well |
Looking now, need to catch up |
Hmm I don't see a way we can do this, because for any given type I did take a stab at a conversion anyways but it did not work. This is the code I was experimenting with that failed: enum ErrorConversion<E> {
StringError(String),
NativeError(E),
}
impl<S: ToString> From<S> for ErrorConversion<()> {
fn from(s: S) -> Self {
Self::StringError(s.to_string())
}
}
impl<E: TryIntoJs> From<E> for ErrorConversion<E> {
fn from(e: E) -> Self {
Self::NativeError(e)
}
}
impl<T, E, C> TryIntoJs for Result<T, C>
where
T: TryIntoJs,
E: TryIntoJs,
C: Into<ErrorConversion<E>>,
{
fn try_to_js(self, js_env: &JsEnv) -> Result<napi_value, NjError> {
match self {
Ok(val) => val.try_to_js(&js_env),
Err(err) => {
let conv = err.into();
match conv {
ErrorConversion::StringError(string) => Err(NjError::Other(string)),
ErrorConversion::NativeError(e) => Err(NjError::Native(e.try_to_js(&js_env))),
}
}
}
}
} This fails to compile with the following error:
I think we should probably accept that this will be a breaking change and move forward with the major version bump. I think the new enum conversion for errors is better than what we had previously. |
K. Let's bump up major version |
Since we are bump up major version, let's see what else can be clean up in terms of API. |
Ok, I'll bump the version here and create the issue shortly... |
Created a stub issue at #156, please comment with any improvements you have in mind. |
I've noticed there is no example/test which tests the new structured errors from |
Great job! |
As the title says, this adds support for auto-conversion of enums into JS. Representation used is the same as the default one in Serde. I took the same choices when it comes to unit variants' representation: they are represented by strings with the value being the variant name in PascalCase. Unit structs are also supported, and represented by
null
s (seeexamples/json
for a hands on outline of different representation possibilities).There is one somewhat breaking change buried in here. The representation of
TryIntoJs for Result<T, E>
no longer demandsE: ToString
, but requiresE: TryIntoJs
. This allows the user to read structured errors in JS, no longer having to rely on just their string representation. If you see a way of achieving the same thing without introducing a breaking change, let me know in the review.