Files
SpotiFLAC-Mobile/lib/services/network_storage_error.dart
T

75 lines
2.8 KiB
Dart

import 'dart:async';
import 'dart:io';
import 'package:dart_smb2/dart_smb2.dart';
import 'package:spotiflac_android/services/network_certificate.dart';
enum NetworkStorageError {
unreachable,
timeout,
authentication,
permission,
missingShare,
incompatible,
invalidAddress,
certificate,
unknown,
}
/// Classify transport failures without exposing URLs, usernames or passwords.
NetworkStorageError classifyNetworkStorageError(Object error) {
if (error is NetworkCertificateException || error is HandshakeException) {
return NetworkStorageError.certificate;
}
if (error is TimeoutException) return NetworkStorageError.timeout;
if (error is SocketException) return NetworkStorageError.unreachable;
if (error is FormatException) return NetworkStorageError.invalidAddress;
final message = switch (error) {
Smb2Exception(:final message) => message,
HttpException(:final message) => message,
String value => value,
_ => '',
}.toLowerCase();
if (message.contains('not compatible') ||
message.contains('does not support smb') ||
message.contains('invalid dialect') ||
message.contains('status_not_supported') ||
message.contains('no matching dialect')) {
return NetworkStorageError.incompatible;
}
if (message.contains('logon failure') ||
message.contains('logon_failure') ||
message.contains('wrong_password') ||
message.contains('password_must_change') ||
message.contains('password_expired') ||
message.contains('account_disabled') ||
message == 'server returned 401') {
return NetworkStorageError.authentication;
}
if (message.contains('access denied') || message == 'server returned 403') {
return NetworkStorageError.permission;
}
if (message == 'server returned 404') return NetworkStorageError.missingShare;
if (message.contains('bad_network_name')) {
return NetworkStorageError.missingShare;
}
if (error is Smb2Exception) {
// A worker-start failure can wrap the native exception as text. Recover
// its transport classification before suggesting a credential change.
final transportType = Smb2ErrorType.fromMessage(message);
return switch (transportType == Smb2ErrorType.unknown
? error.type
: transportType) {
Smb2ErrorType.connection => NetworkStorageError.unreachable,
Smb2ErrorType.timeout => NetworkStorageError.timeout,
Smb2ErrorType.auth => NetworkStorageError.authentication,
Smb2ErrorType.accessDenied => NetworkStorageError.permission,
Smb2ErrorType.fileNotFound ||
Smb2ErrorType.notADirectory => NetworkStorageError.missingShare,
Smb2ErrorType.invalidParam => NetworkStorageError.invalidAddress,
_ => NetworkStorageError.unknown,
};
}
return NetworkStorageError.unknown;
}