formatErrorMessage method
Normalises an arbitrary throwable into an ApiError.
Matching is done with is checks rather than on
runtimeType.toString(): the latter silently stops matching under
release obfuscation (--obfuscate) and never matches subclasses.
An error that is already an ApiError is returned unchanged, so a
custom error thrown by an interceptor keeps its own message and code.
Implementation
ApiError formatErrorMessage(dynamic error, String defaultErrorMessage) {
if (error is ApiError) return error;
final String message;
final int code;
if (error is SocketException ||
error is HttpException ||
error is RedirectException ||
error is WebSocketException) {
message = 'Please check your internet connection and try again';
code = ErrorCodes.network;
} else if (error is HandshakeException) {
message = 'Could not establish secure connection with the server';
code = ErrorCodes.handshake;
} else if (error is CertificateException) {
message = 'An error occurred, could not verify server certificate';
code = ErrorCodes.certificate;
} else if (error is FileSystemException) {
message = 'A filesystem exception has occurred';
code = ErrorCodes.fileSystem;
} else if (error is TlsException) {
message = 'SSL error occurred ${error.message}';
code = ErrorCodes.tls;
} else if (error is ClientException) {
message = 'Client exception occurred, could not connect to the server';
code = ErrorCodes.client;
} else if (error is TimeoutException) {
message = 'Connection Timed out please check your internet connection';
code = ErrorCodes.timeout;
} else if (error is FormatException) {
message = 'Improperly formatted value';
code = ErrorCodes.format;
} else if (error is MissingPluginException) {
message = 'Plugin not found';
code = ErrorCodes.missingPlugin;
} else if (error is NetworkImageLoadException) {
message = 'Could not load the image';
code = ErrorCodes.imageLoad;
} else if (error.toString().contains('SocketException')) {
// Some platforms wrap the socket failure in an opaque type.
message = 'Please check your internet connection and try again';
code = ErrorCodes.network;
} else {
ApiConfig().log('unmapped error ${error.runtimeType}: $error');
message = defaultErrorMessage.isNotEmpty
? defaultErrorMessage
: ApiConfig().defaultErrorMessage;
code = ErrorCodes.unknown;
}
return ApiError(message, code);
}