diff --git a/lib/src/hosted_source.dart b/lib/src/hosted_source.dart index 43922a21aae3287698e9f5f1fbe9737159b927a7..70b1440d297f093da1e20b8aad333f857786939e 100644 --- a/lib/src/hosted_source.dart +++ b/lib/src/hosted_source.dart @@ -119,6 +119,8 @@ class HostedSource extends Source { /// this tries to translate into a more user friendly error message. Always /// throws an error, either the original one or a better one. void _throwFriendlyError(ex, package, url) { + ex = getRealError(ex); + if (ex is PubHttpException && ex.response.statusCode == 404) { throw 'Could not find package "$package" at $url.'; } diff --git a/lib/src/http.dart b/lib/src/http.dart index 7218562f0868ecb1831884f513b09313fd4b2f7d..1c349786a1ced8b7f98f52838cdb8452ed3675cc 100644 --- a/lib/src/http.dart +++ b/lib/src/http.dart @@ -14,6 +14,7 @@ import '../../pkg/http/lib/http.dart' as http; import 'curl_client.dart'; import 'io.dart'; import 'log.dart' as log; +import 'utils.dart'; // TODO(nweiz): make this configurable /// The amount of time in milliseconds to allow HTTP requests before assuming @@ -57,6 +58,7 @@ class PubHttpClient extends http.BaseClient { throw new PubHttpException(response); }); }).catchError((e) { + e = getRealError(e); if (e is SocketIOException && e.osError != null && (e.osError.errorCode == 8 || diff --git a/lib/src/utils.dart b/lib/src/utils.dart index b922d845d4013de9e3132acb6033f3e2e5fa86b4..544a3ce0bef5c1c9a9d99dc98154aa04694a91d3 100644 --- a/lib/src/utils.dart +++ b/lib/src/utils.dart @@ -183,3 +183,14 @@ void mapAddAll(Map destination, Map source) => /// replacing `+` with ` `. String urlDecode(String encoded) => decodeUriComponent(encoded.replaceAll("+", " ")); + +// TODO(rnystrom): Remove this when #7781 is fixed. +/// When an error is rethrown in an async callback, you can end up with nested +/// AsyncErrors. This unwraps them to find the real originating error. +getRealError(error) { + while (error is AsyncError) { + error = error.error; + } + + return error; +}