Skip to content

Commit

Permalink
feat(bindings/nodejs): better error code
Browse files Browse the repository at this point in the history
Signed-off-by: tison <[email protected]>
  • Loading branch information
tisonkun committed Jul 8, 2024
1 parent e6ccc8f commit 751a48c
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 14 deletions.
18 changes: 14 additions & 4 deletions bin/ofs/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 8 additions & 4 deletions bindings/nodejs/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,11 @@ Contains the following tools:

```bash
# Install dependencies.
> pnpm install
pnpm install
# Build from source.
> pnpm build
pnpm build
# Build from source with debug info.
> pnpm build:debug
pnpm build:debug
```

## Test
Expand All @@ -92,8 +92,12 @@ We are using our own developed behavior testing framework.
Taking 'service-memory' as an example, you can use the following command to run it.

```bash
> OPENDAL_TEST=memory pnpm test
OPENDAL_TEST=memory pnpm test
```

which will output:

```
✓ |opendal| tests/service.test.mjs (8 tests | 2 skipped) 40ms
Test Files 1 passed (1)
Expand Down
86 changes: 80 additions & 6 deletions bindings/nodejs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ use napi::bindgen_prelude::*;

mod capability;

type Result<T> = napi::Result<T, ErrorCode>;

#[napi]
pub struct Operator(opendal::Operator);

Expand Down Expand Up @@ -755,13 +757,30 @@ pub struct Reader {
impl Reader {
/// # Safety
///
/// > &mut self in async napi methods should be marked as unsafe
/// `&mut self` in async napi methods should be marked as unsafe
///
/// Read bytes from this reader into given buffer.
#[napi]
pub async unsafe fn read(&mut self, mut buf: Buffer) -> Result<usize> {
let buf = buf.as_mut();
let n = self.inner.read(buf).await.map_err(format_napi_error)?;
let n = self
.inner
.read(buf)
.await
.map_err(|e| {
opendal::Error::new(
match e.kind() {
std::io::ErrorKind::NotFound => opendal::ErrorKind::NotFound,
std::io::ErrorKind::PermissionDenied => {
opendal::ErrorKind::PermissionDenied
}
_ => opendal::ErrorKind::Unexpected,
},
"failed to read bytes",
)
.set_source(e)
})
.map_err(format_napi_error)?;
Ok(n)
}
}
Expand Down Expand Up @@ -1144,9 +1163,64 @@ impl RetryLayer {
}
}

#[repr(i32)]
#[non_exhaustive]
#[derive(Eq, PartialEq, Debug, Clone, Copy)]
enum ErrorCode {
Unexpected = 1001,
Unsupported = 1002,
ConfigInvalid = 1003,
NotFound = 1004,
PermissionDenied = 1005,
IsADirectory = 1006,
NotADirectory = 1007,
AlreadyExists = 1008,
RateLimited = 1009,
IsSameFile = 1010,
ConditionNotMatch = 1011,
RangeNotSatisfied = 1012,
}

impl AsRef<str> for ErrorCode {
fn as_ref(&self) -> &str {
match self {
ErrorCode::Unexpected => "Unexpected",
ErrorCode::Unsupported => "Unsupported",
ErrorCode::ConfigInvalid => "ConfigInvalid",
ErrorCode::NotFound => "NotFound",
ErrorCode::PermissionDenied => "PermissionDenied",
ErrorCode::IsADirectory => "IsADirectory",
ErrorCode::NotADirectory => "NotADirectory",
ErrorCode::AlreadyExists => "AlreadyExists",
ErrorCode::RateLimited => "RateLimited",
ErrorCode::IsSameFile => "IsSameFile",
ErrorCode::ConditionNotMatch => "ConditionNotMatch",
ErrorCode::RangeNotSatisfied => "RangeNotSatisfied",
}
}
}

impl From<opendal::Error> for ErrorCode {
fn from(err: opendal::Error) -> Self {
match err.kind() {
opendal::ErrorKind::Unexpected => ErrorCode::Unexpected,
opendal::ErrorKind::Unsupported => ErrorCode::Unsupported,
opendal::ErrorKind::ConfigInvalid => ErrorCode::ConfigInvalid,
opendal::ErrorKind::NotFound => ErrorCode::NotFound,
opendal::ErrorKind::PermissionDenied => ErrorCode::PermissionDenied,
opendal::ErrorKind::IsADirectory => ErrorCode::IsADirectory,
opendal::ErrorKind::NotADirectory => ErrorCode::NotADirectory,
opendal::ErrorKind::AlreadyExists => ErrorCode::AlreadyExists,
opendal::ErrorKind::RateLimited => ErrorCode::RateLimited,
opendal::ErrorKind::IsSameFile => ErrorCode::IsSameFile,
opendal::ErrorKind::ConditionNotMatch => ErrorCode::ConditionNotMatch,
opendal::ErrorKind::RangeNotSatisfied => ErrorCode::RangeNotSatisfied,
kind => unimplemented!("error kind not supported: {:?}", kind),
}
}
}

/// Format opendal error to napi error.
///
/// FIXME: handle error correctly.
fn format_napi_error(err: impl Display) -> Error {
Error::from_reason(format!("{}", err))
fn format_napi_error(err: opendal::Error) -> Error<ErrorCode> {
Error::new(err.kind().into(), err.to_string())
}

0 comments on commit 751a48c

Please sign in to comment.