質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

Dart

Dartは、Googleによって開発されたJavaScriptの代替となることを目的に作られた、ウェブ向けのプログラミング言語である。

Q&A

1回答

1787閲覧

Dart FutureクラスのcatchError()メソッドでのエラー捕捉について

moriman

総合スコア615

Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

Dart

Dartは、Googleによって開発されたJavaScriptの代替となることを目的に作られた、ウェブ向けのプログラミング言語である。

0グッド

0クリップ

投稿2020/06/08 02:48

https://dart.dev/guides/libraries/library-tour#dartasync---asynchronous-programming

上記ページのエラー処理の説明を読んでいるんですが、

Important: Be sure to invoke catchError() on the result of then()—not on the result of the original Future. Otherwise, the catchError() can handle errors only from the original Future’s computation, but not from the handler registered by then().

上記の説明なんですが、これは例えば

//sample1 Future<String> one() => new Future.value("from one1"); Future<String> twoOne() => new Future.error("error from 21"); Future<void> main() async { one() .catchError( (e){ print("エラー内容 : $e"); } ); } /* (何も表示されない) */

sample1の呼び出し方だと、one()が返すfutureのエラーしかキャッチできませんよ。(上記コードではone()でエラーは出ないので、エラー内容は何も表示されませんが)
しかし

//sample2 Future<String> one() => new Future.value("from one1"); Future<String> twoOne() => new Future.error("error from 21"); Future<void> main() async { one() .then( (_){ print("one completed"); twoOne(); } ) .catchError( (e){ print("エラー内容 : $e"); } ); } /* one completed */

sample2のように呼び出せば、thenのコールバックの中で発生したエラー(つまりtwoOne()のエラー)もcatchError()メソッドで捕捉できますよ。

という説明ではないんでしょうか?そうとしか読めないんですが。

でも実際動かしてみると

one completed

しか表示されません。これって
twoOne()
で発生したエラーがcatchError()メソッドで捕捉されていないと思うのですが。

これって何なんでしょうか。仕様が変わったけどドキュメントに反映されていない、みたいなことなんでしょうか。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

satokei

2020/06/08 04:17

> but not from the handler registered by then(). 私は、then()で発生したエラーは補足できないと理解しました。
moriman

2020/06/10 03:42

回答を頂きましてありがとうございます。 私としては、英文の訳は、 重要:catchErrorはオリジナルのfutureに対してではなく、thenの返り値に対して呼び出しましょう。そうしないと、catchErrorはオリジナルのfutureの計算のエラー処理しかできません。thenで登録されたhandler(コールバック)のエラーを処理できません。 という認識です。この訳だと、「thenの返り値に対してcatchErrorを呼び出せば、thenのコールバックでのエラーも捕捉できる」ということなのではないか?という認識なのですが。
satokei

2020/06/29 03:21

返答が遅くなりました。 私の理解が間違っていましたが、私なりに理解した内容を回答いたしました。
guest

回答1

0

おそらく該当の文章は、以下を意図しているのだと思います。

  • 間違った記述

dart

1 one() 2 .catchError((e) { 3 print("エラー内容 : $e"); 4 }) 5 .then((_) { 6 print("one completed"); 7 throw "error!!"; 8 }); 9/*=== 実行結果 === 10one completed 11*/
  • 正しい記述

dart

1 await one() 2 .then((_) { 3 print("one completed"); 4 throw "error!!"; 5 }) 6 .catchError((e) { 7 print("エラー内容 : $e"); 8 }); 9/*=== 実行結果 === 10one completed 11エラー内容 : error!! 12*/

 

質問のコード「sample2」は、
以下のように記述すると意図した動作になりますので、
エラーの投げ方の問題のような気がします。

dart

1 one() 2 .then( 3 (_) async { 4 print("one completed"); 5 await twoOne(); 6 } 7 ) 8 .catchError( 9 (e){ 10 print("エラー内容 : $e"); 11 } 12 );

 
ちなみに、通常は以下のように記述すると思います。

dart

1 one() 2 .then((_) => print("one completed")) 3 .then((_) => twoOne()) 4 .catchError((e) { 5 print("エラー内容 : $e"); 6 });

投稿2020/06/29 03:21

satokei

総合スコア1217

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問