Skip to content

Commit 78d6114

Browse files
authored
Add a new exception type NSErrorClientException (#1763)
1 parent 7a2e7d5 commit 78d6114

File tree

6 files changed

+65
-7
lines changed

6 files changed

+65
-7
lines changed

pkgs/cupertino_http/CHANGELOG.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
## 2.1.2-wip
1+
## 2.2.0
22

33
* Cancel requests when the response stream is cancelled.
4+
* Add a new exception type `NSErrorClientException` that contains the
5+
`NSError` associated with the failure.
46

57
## 2.1.1
68

pkgs/cupertino_http/example/integration_test/client_profile_test.dart

+4-2
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,8 @@ void main() {
164164
expect(profile.requestData.bodyBytes, 'Hi'.codeUnits);
165165
expect(profile.requestData.contentLength, 2);
166166
expect(profile.requestData.endTime, isNotNull);
167-
expect(profile.requestData.error, startsWith('ClientException:'));
167+
expect(
168+
profile.requestData.error, startsWith('NSErrorClientException:'));
168169
expect(
169170
profile.requestData.headers, containsPair('Content-Length', ['2']));
170171
expect(profile.requestData.headers,
@@ -247,7 +248,8 @@ void main() {
247248
expect(profile.responseData.compressionState, isNull);
248249
expect(profile.responseData.contentLength, 11);
249250
expect(profile.responseData.endTime, isNotNull);
250-
expect(profile.responseData.error, startsWith('ClientException:'));
251+
expect(
252+
profile.responseData.error, startsWith('NSErrorClientException:'));
251253
expect(profile.responseData.headers,
252254
containsPair('content-type', ['text/plain']));
253255
expect(profile.responseData.headers,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'package:cupertino_http/cupertino_http.dart';
6+
import 'package:flutter_test/flutter_test.dart';
7+
import 'package:integration_test/integration_test.dart';
8+
import 'package:objective_c/objective_c.dart';
9+
10+
void main() {
11+
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
12+
13+
group('NSErrorClientException', () {
14+
late CupertinoClient client;
15+
16+
setUpAll(() => client = CupertinoClient.defaultSessionConfiguration());
17+
tearDownAll(() => client.close());
18+
19+
test('thrown', () async {
20+
expect(
21+
() => client.get(Uri.http('doesnotexist', '/')),
22+
throwsA(isA<NSErrorClientException>()
23+
.having((e) => e.error.domain.toDartString(), 'error.domain',
24+
'NSURLErrorDomain')
25+
.having((e) => e.error.code, 'error.code', -1003)
26+
.having(
27+
(e) => e.toString(),
28+
'toString()',
29+
'NSErrorClientException: A server with the specified '
30+
'hostname could not be found. '
31+
'[domain=NSURLErrorDomain, code=-1003], '
32+
'uri=http://doesnotexist/')));
33+
});
34+
});
35+
}

pkgs/cupertino_http/lib/cupertino_http.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -92,5 +92,5 @@ import 'package:http/http.dart';
9292
import 'src/cupertino_client.dart';
9393

9494
export 'src/cupertino_api.dart';
95-
export 'src/cupertino_client.dart' show CupertinoClient;
95+
export 'src/cupertino_client.dart' show CupertinoClient, NSErrorClientException;
9696
export 'src/cupertino_web_socket.dart';

pkgs/cupertino_http/lib/src/cupertino_client.dart

+21-2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,26 @@ final _digitRegex = RegExp(r'^\d+$');
1717

1818
const _nsurlErrorCancelled = -999;
1919

20+
/// A [ClientException] generated from an [NSError].
21+
class NSErrorClientException extends ClientException {
22+
final NSError error;
23+
24+
NSErrorClientException(this.error, [Uri? uri])
25+
: super(error.localizedDescription.toDartString(), uri);
26+
27+
@override
28+
String toString() {
29+
final b = StringBuffer(
30+
'NSErrorClientException: ${error.localizedDescription.toDartString()} '
31+
'[domain=${error.domain.toDartString()}, code=${error.code}]');
32+
33+
if (uri != null) {
34+
b.write(', uri=$uri');
35+
}
36+
return b.toString();
37+
}
38+
}
39+
2040
/// This class can be removed when `package:http` v2 is released.
2141
class _StreamedResponseWithUrl extends StreamedResponse
2242
implements BaseResponseWithUrl {
@@ -176,8 +196,7 @@ class CupertinoClient extends BaseClient {
176196
if (error != null &&
177197
!(error.domain.toDartString() == 'NSURLErrorDomain' &&
178198
error.code == _nsurlErrorCancelled)) {
179-
final exception = ClientException(
180-
error.localizedDescription.toDartString(), taskTracker.request.url);
199+
final exception = NSErrorClientException(error, taskTracker.request.url);
181200
if (taskTracker.profile != null &&
182201
taskTracker.profile!.requestData.endTime == null) {
183202
// Error occurred during the request.

pkgs/cupertino_http/pubspec.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: cupertino_http
2-
version: 2.1.2-wip
2+
version: 2.2.0-wip
33
description: >-
44
A macOS/iOS Flutter plugin that provides access to the Foundation URL
55
Loading System.

0 commit comments

Comments
 (0)