mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Add native stacktrace field for PlatformException. (#64199)
This commit is contained in:
parent
c3a47b3449
commit
abbd5b149a
@ -80,9 +80,9 @@ abstract class MethodCodec {
|
||||
|
||||
/// Encodes an error result into a binary envelope.
|
||||
///
|
||||
/// The specified error [code], human-readable error [message], and error
|
||||
/// The specified error [code], human-readable error [message] and error
|
||||
/// [details] correspond to the fields of [PlatformException].
|
||||
ByteData encodeErrorEnvelope({ required String code, String? message, dynamic details });
|
||||
ByteData encodeErrorEnvelope({ required String code, String? message, dynamic details});
|
||||
}
|
||||
|
||||
|
||||
@ -107,6 +107,7 @@ class PlatformException implements Exception {
|
||||
required this.code,
|
||||
this.message,
|
||||
this.details,
|
||||
this.stacktrace,
|
||||
}) : assert(code != null);
|
||||
|
||||
/// An error code.
|
||||
@ -118,8 +119,18 @@ class PlatformException implements Exception {
|
||||
/// Error details, possibly null.
|
||||
final dynamic details;
|
||||
|
||||
/// Native stacktrace for the error, possibly null.
|
||||
/// This is strictly for native platform stacktrace.
|
||||
/// The stacktrace info on dart platform can be found within the try-catch block for example:
|
||||
/// try {
|
||||
/// ...
|
||||
/// } catch (e, stacktrace) {
|
||||
/// print(stacktrace);
|
||||
/// }
|
||||
final String? stacktrace;
|
||||
|
||||
@override
|
||||
String toString() => 'PlatformException($code, $message, $details)';
|
||||
String toString() => 'PlatformException($code, $message, $details, $stacktrace)';
|
||||
}
|
||||
|
||||
/// Thrown to indicate that a platform interaction failed to find a handling
|
||||
|
||||
@ -152,6 +152,16 @@ class JSONMethodCodec implements MethodCodec {
|
||||
message: decoded[1] as String,
|
||||
details: decoded[2],
|
||||
);
|
||||
if (decoded.length == 4
|
||||
&& decoded[0] is String
|
||||
&& (decoded[1] == null || decoded[1] is String)
|
||||
&& (decoded[3] == null || decoded[3] is String))
|
||||
throw PlatformException(
|
||||
code: decoded[0] as String,
|
||||
message: decoded[1] as String,
|
||||
details: decoded[2],
|
||||
stacktrace: decoded[3] as String,
|
||||
);
|
||||
throw FormatException('Invalid envelope: $decoded');
|
||||
}
|
||||
|
||||
@ -161,7 +171,7 @@ class JSONMethodCodec implements MethodCodec {
|
||||
}
|
||||
|
||||
@override
|
||||
ByteData encodeErrorEnvelope({ required String code, String? message, dynamic details }) {
|
||||
ByteData encodeErrorEnvelope({ required String code, String? message, dynamic details}) {
|
||||
assert(code != null);
|
||||
return const JSONMessageCodec().encodeMessage(<dynamic>[code, message, details])!;
|
||||
}
|
||||
@ -547,7 +557,7 @@ class StandardMethodCodec implements MethodCodec {
|
||||
}
|
||||
|
||||
@override
|
||||
ByteData encodeErrorEnvelope({ required String code, String? message, dynamic details }) {
|
||||
ByteData encodeErrorEnvelope({ required String code, String? message, dynamic details}) {
|
||||
final WriteBuffer buffer = WriteBuffer();
|
||||
buffer.putUint8(1);
|
||||
messageCodec.writeValue(buffer, code);
|
||||
@ -567,8 +577,9 @@ class StandardMethodCodec implements MethodCodec {
|
||||
final dynamic errorCode = messageCodec.readValue(buffer);
|
||||
final dynamic errorMessage = messageCodec.readValue(buffer);
|
||||
final dynamic errorDetails = messageCodec.readValue(buffer);
|
||||
final String? errorStacktrace = (buffer.hasRemaining) ? messageCodec.readValue(buffer) as String : null;
|
||||
if (errorCode is String && (errorMessage == null || errorMessage is String) && !buffer.hasRemaining)
|
||||
throw PlatformException(code: errorCode, message: errorMessage as String, details: errorDetails);
|
||||
throw PlatformException(code: errorCode, message: errorMessage as String, details: errorDetails, stacktrace: errorStacktrace);
|
||||
else
|
||||
throw const FormatException('Invalid envelope');
|
||||
}
|
||||
|
||||
@ -7,9 +7,12 @@
|
||||
// This files contains message codec tests that are supported both on the Web
|
||||
// and in the VM. For VM-only tests see message_codecs_vm_test.dart.
|
||||
|
||||
import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:flutter/foundation.dart' show WriteBuffer;
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:matcher/matcher.dart';
|
||||
import '../flutter_test_alternative.dart';
|
||||
import 'message_codecs_testing.dart';
|
||||
|
||||
@ -36,14 +39,77 @@ void main() {
|
||||
final ByteData helloByteData = string.encodeMessage('hello');
|
||||
|
||||
final ByteData offsetByteData = ByteData.view(
|
||||
helloWorldByteData.buffer,
|
||||
helloByteData.lengthInBytes,
|
||||
helloWorldByteData.lengthInBytes - helloByteData.lengthInBytes,
|
||||
helloWorldByteData.buffer,
|
||||
helloByteData.lengthInBytes,
|
||||
helloWorldByteData.lengthInBytes - helloByteData.lengthInBytes,
|
||||
);
|
||||
|
||||
expect(string.decodeMessage(offsetByteData), ' world');
|
||||
});
|
||||
});
|
||||
group('Standard method codec', () {
|
||||
const MethodCodec method = StandardMethodCodec();
|
||||
const StandardMessageCodec messageCodec = StandardMessageCodec();
|
||||
test('should decode error envelope without native stacktrace', () {
|
||||
final ByteData errorData = method.encodeErrorEnvelope(
|
||||
code: 'errorCode',
|
||||
message: 'errorMessage',
|
||||
details: 'errorDetails',
|
||||
);
|
||||
expect(
|
||||
() => method.decodeEnvelope(errorData),
|
||||
throwsA(predicate((PlatformException e) =>
|
||||
e is PlatformException &&
|
||||
e.code == 'errorCode' &&
|
||||
e.message == 'errorMessage' &&
|
||||
e.details == 'errorDetails')));
|
||||
});
|
||||
test('should decode error envelope with native stacktrace.', () {
|
||||
final WriteBuffer buffer = WriteBuffer();
|
||||
buffer.putUint8(1);
|
||||
messageCodec.writeValue(buffer, 'errorCode');
|
||||
messageCodec.writeValue(buffer, 'errorMessage');
|
||||
messageCodec.writeValue(buffer, 'errorDetails');
|
||||
messageCodec.writeValue(buffer, 'errorStacktrace');
|
||||
final ByteData errorData = buffer.done();
|
||||
expect(
|
||||
() => method.decodeEnvelope(errorData),
|
||||
throwsA(predicate((PlatformException e) =>
|
||||
e is PlatformException && e.stacktrace == 'errorStacktrace')));
|
||||
});
|
||||
});
|
||||
group('Json method codec', () {
|
||||
const JsonCodec json = JsonCodec();
|
||||
const StringCodec stringCodec = StringCodec();
|
||||
const JSONMethodCodec jsonMethodCodec = JSONMethodCodec();
|
||||
test('should decode error envelope without native stacktrace', () {
|
||||
final ByteData errorData = jsonMethodCodec.encodeErrorEnvelope(
|
||||
code: 'errorCode',
|
||||
message: 'errorMessage',
|
||||
details: 'errorDetails',
|
||||
);
|
||||
expect(
|
||||
() => jsonMethodCodec.decodeEnvelope(errorData),
|
||||
throwsA(predicate((PlatformException e) =>
|
||||
e is PlatformException &&
|
||||
e.code == 'errorCode' &&
|
||||
e.message == 'errorMessage' &&
|
||||
e.details == 'errorDetails')));
|
||||
});
|
||||
test('should decode error envelope with native stacktrace.', () {
|
||||
final ByteData errorData = stringCodec.encodeMessage(json
|
||||
.encode(<dynamic>[
|
||||
'errorCode',
|
||||
'errorMessage',
|
||||
'errorDetails',
|
||||
'errorStacktrace'
|
||||
]));
|
||||
expect(
|
||||
() => jsonMethodCodec.decodeEnvelope(errorData),
|
||||
throwsA(predicate((PlatformException e) =>
|
||||
e is PlatformException && e.stacktrace == 'errorStacktrace')));
|
||||
});
|
||||
});
|
||||
group('JSON message codec', () {
|
||||
const MessageCodec<dynamic> json = JSONMessageCodec();
|
||||
test('should encode and decode simple messages', () {
|
||||
@ -151,8 +217,22 @@ void main() {
|
||||
standard,
|
||||
1.0,
|
||||
<int>[
|
||||
6, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0xf0, 0x3f,
|
||||
6,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0xf0,
|
||||
0x3f,
|
||||
],
|
||||
);
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user