Skip to content
GitLab
Next
Menu
Why GitLab
Pricing
Contact Sales
Explore
Why GitLab
Pricing
Contact Sales
Explore
Sign in
Get free trial
Changes
Page history
Update rust error
authored
Dec 03, 2021
by
umaumax
Show whitespace changes
Inline
Side-by-side
rust/rust-error.md
View page @
d6890e77
...
@@ -118,7 +118,7 @@ ResultのEがErrorトレイトを満たす単なる構造体については`?`
...
@@ -118,7 +118,7 @@ ResultのEがErrorトレイトを満たす単なる構造体については`?`
そのまま返すと
`trait `
Sized
` is not implemented`
となるので、間に変換を挟む必要がある
そのまま返すと
`trait `
Sized
` is not implemented`
となるので、間に変換を挟む必要がある
(このテクニックはlifetime境界が含まれるエラー型から新規の
`'static`
なエラー型を生成する場合にも使える)
(このテクニックはlifetime境界が含まれるエラー型から新規の
`'static`
なエラー型を生成する場合にも使える)
参考:
[
Explicit constructor from Box<dyn Error + Send + Sync> · Issue #83 · dtolnay/anyhow
](
https://github.com/dtolnay/anyhow/issues/83
)
参考:
[
Explicit constructor from Box
\
<dyn Error + Send + Sync> · Issue #83 · dtolnay/anyhow
](
https://github.com/dtolnay/anyhow/issues/83
)
[
Error in anyhow - Rust
](
https://docs.rs/anyhow/1.0.44/anyhow/struct.Error.html#impl-From%3CError%3E
)
に
`Send`
や
`Sync`
なしの
`impl From<Error> for Box<dyn StdError + 'static>`
も存在するが、
[
Error in anyhow - Rust
](
https://docs.rs/anyhow/1.0.44/anyhow/struct.Error.html#impl-From%3CError%3E
)
に
`Send`
や
`Sync`
なしの
`impl From<Error> for Box<dyn StdError + 'static>`
も存在するが、
ソースコードを見るとラップされているだけであり、内部では
`impl From<Error> for Box<dyn StdError + Send + Sync + 'static>`
を呼びだす
ソースコードを見るとラップされているだけであり、内部では
`impl From<Error> for Box<dyn StdError + Send + Sync + 'static>`
を呼びだす
...
@@ -132,7 +132,7 @@ ResultのEがErrorトレイトを満たす単なる構造体については`?`
...
@@ -132,7 +132,7 @@ ResultのEがErrorトレイトを満たす単なる構造体については`?`
自然に
`Send`
や
`Sync`
の条件を満たしているので、特に意識することなく、
`From`
トレイトによって、自動変換されていることがわかる
自然に
`Send`
や
`Sync`
の条件を満たしているので、特に意識することなく、
`From`
トレイトによって、自動変換されていることがわかる
ただし、
ただし、
[
rust - Why doesn't Box<dyn Error> implement Error? - Stack Overflow
](
https://stackoverflow.com/questions/65151237/why-doesnt-boxdyn-error-implement-error
)
[
rust - Why doesn't Box
\
<dyn Error> implement Error? - Stack Overflow
](
https://stackoverflow.com/questions/65151237/why-doesnt-boxdyn-error-implement-error
)
にある通り、下記のように変換しようとすると
`Sized`
が実装されておらず変換できない
にある通り、下記のように変換しようとすると
`Sized`
が実装されておらず変換できない
```
rust
```
rust
let
box_error
:
Box
<
dyn
std
::
error
::
Error
+
Send
+
Sync
+
'static
>
=
todo!
();
let
box_error
:
Box
<
dyn
std
::
error
::
Error
+
Send
+
Sync
+
'static
>
=
todo!
();
...
@@ -302,3 +302,56 @@ std::fs::File::open(path).with_context(|| format!("Failed to open config file: {
...
@@ -302,3 +302,56 @@ std::fs::File::open(path).with_context(|| format!("Failed to open config file: {
```
```
`use anyhow::Context`
によって、
`std::error::Error`
に
`.context()`
などが生える
`use anyhow::Context`
によって、
`std::error::Error`
に
`.context()`
などが生える
## `ensure!`の調査
要約:
`failchain::ensure`
を利用するか内部で定義するかの2通りがある
*
[
failchain::ensure - Rust
](
https://docs.rs/failchain/latest/failchain/macro.ensure.html
)
:
`Err($e.into())`
*
`ensure!`
が任意のエラー型で利用可能!!
*
有名ではないが、
`ensure!`
のみならば特に問題ないのでは?
*
[
snafu::ensure - Rust
](
https://docs.rs/snafu/0.6.10/snafu/macro.ensure.html
)
:
`.fail().map_err(::core::convert::Into::into);`
*
`ensure!`
は
`.fail()`
を持つ型で利用可能...
*
[
ensure in anyhow - Rust
](
https://docs.rs/anyhow/1.0.51/anyhow/macro.ensure.html
)
:
`private::Err(anyhow!())`
*
`anyhow::Error`
以外では
`ensure!`
が利用できない...
*
凍結注意
[
failure::ensure - Rust
](
https://docs.rs/failure/latest/failure/macro.ensure.html
)
:
`failure::Error`
*
凍結注意
[
error_chain::ensure - Rust
](
https://docs.rs/error-chain/0.12.4/error_chain/macro.ensure.html
)
:
`Err($e.into())`
*
内部定義例
*
[
minsc/macros.rs at master · shesek/minsc
](
https://github.com/shesek/minsc/blob/master/src/macros.rs
)
*
[
zola/lib.rs at master · getzola/zola
](
https://github.com/getzola/zola/blob/master/components/errors/src/lib.rs
)
*
[
notify-rust/error.rs at main · hoodie/notify-rust
](
https://github.com/hoodie/notify-rust/blob/main/src/error.rs
)
FYI:
[
Err($e.into()) - grep.app
](
https://grep.app/search?q=Err%28%24e.into%28%29%29
)
```
rust
#[macro_export]
#[doc(hidden)]
macro_rules!
ensure
{
(
$cond:expr
,
$e:expr
)
=>
{
if
!
(
$cond
)
{
crate
::
bail!
(
$e
);
}
};
(
$cond:expr
,
$fmt:expr
,
$
(
$arg:tt
)
*
)
=>
{
if
!
(
$cond
)
{
crate
::
bail!
(
$fmt
,
$
(
$arg
)
*
);
}
};
}
#[macro_export]
#[doc(hidden)]
macro_rules!
bail
{
(
$e:expr
)
=>
{
return
Err
(
$e
.into
());
};
(
$fmt:expr
,
$
(
$arg:tt
)
+
)
=>
{
return
Err
(
format!
(
$fmt
,
$
(
$arg
)
+
)
.into
());
};
}
```
内部クレートの他のモジュールから利用する場合には下記の宣言が必要
```
rust
use
crate
::
ensure
;
use
crate
::
bail
;
```
\ No newline at end of file