mirror of
https://github.com/immich-app/immich.git
synced 2025-09-29 15:31:13 -04:00
chore: show error message in upload details route (#22472)
* chore: show error message in upload details route * pretty format exception --------- Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
This commit is contained in:
parent
ee3c07d049
commit
75b9bd163e
@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
extension StringExtension on String {
|
extension StringExtension on String {
|
||||||
String capitalize() {
|
String capitalize() {
|
||||||
return split(" ").map((str) => str.isEmpty ? str : str[0].toUpperCase() + str.substring(1)).join(" ");
|
return split(" ").map((str) => str.isEmpty ? str : str[0].toUpperCase() + str.substring(1)).join(" ");
|
||||||
@ -23,3 +25,11 @@ extension DurationExtension on String {
|
|||||||
return int.parse(this);
|
return int.parse(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic>? tryJsonDecode(dynamic json) {
|
||||||
|
try {
|
||||||
|
return jsonDecode(json) as Map<String, dynamic>;
|
||||||
|
} catch (e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import 'package:auto_route/auto_route.dart';
|
import 'package:auto_route/auto_route.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
||||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||||
import 'package:immich_mobile/extensions/translate_extensions.dart';
|
import 'package:immich_mobile/extensions/translate_extensions.dart';
|
||||||
import 'package:immich_mobile/providers/backup/drift_backup.provider.dart';
|
|
||||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
|
||||||
import 'package:immich_mobile/providers/infrastructure/asset.provider.dart';
|
|
||||||
import 'package:immich_mobile/presentation/widgets/images/thumbnail.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/images/thumbnail.widget.dart';
|
||||||
|
import 'package:immich_mobile/providers/backup/drift_backup.provider.dart';
|
||||||
|
import 'package:immich_mobile/providers/infrastructure/asset.provider.dart';
|
||||||
import 'package:immich_mobile/utils/bytes_units.dart';
|
import 'package:immich_mobile/utils/bytes_units.dart';
|
||||||
import 'package:path/path.dart' as path;
|
import 'package:path/path.dart' as path;
|
||||||
|
|
||||||
@ -82,6 +82,7 @@ class DriftUploadDetailPage extends ConsumerWidget {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
spacing: 4,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
path.basename(item.filename),
|
path.basename(item.filename),
|
||||||
@ -89,7 +90,13 @@ class DriftUploadDetailPage extends ConsumerWidget {
|
|||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 4),
|
if (item.error != null)
|
||||||
|
Text(
|
||||||
|
item.error!,
|
||||||
|
style: context.textTheme.bodySmall?.copyWith(
|
||||||
|
color: context.colorScheme.onErrorContainer.withValues(alpha: 0.6),
|
||||||
|
),
|
||||||
|
),
|
||||||
Text(
|
Text(
|
||||||
'Tap for more details',
|
'Tap for more details',
|
||||||
style: context.textTheme.bodySmall?.copyWith(
|
style: context.textTheme.bodySmall?.copyWith(
|
||||||
|
@ -7,6 +7,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|||||||
import 'package:immich_mobile/constants/constants.dart';
|
import 'package:immich_mobile/constants/constants.dart';
|
||||||
import 'package:immich_mobile/domain/models/album/local_album.model.dart';
|
import 'package:immich_mobile/domain/models/album/local_album.model.dart';
|
||||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
||||||
|
import 'package:immich_mobile/extensions/string_extensions.dart';
|
||||||
import 'package:immich_mobile/infrastructure/repositories/backup.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/backup.repository.dart';
|
||||||
import 'package:immich_mobile/providers/infrastructure/asset.provider.dart';
|
import 'package:immich_mobile/providers/infrastructure/asset.provider.dart';
|
||||||
import 'package:immich_mobile/providers/user.provider.dart';
|
import 'package:immich_mobile/providers/user.provider.dart';
|
||||||
@ -35,6 +36,7 @@ class DriftUploadStatus {
|
|||||||
final int fileSize;
|
final int fileSize;
|
||||||
final String networkSpeedAsString;
|
final String networkSpeedAsString;
|
||||||
final bool? isFailed;
|
final bool? isFailed;
|
||||||
|
final String? error;
|
||||||
|
|
||||||
const DriftUploadStatus({
|
const DriftUploadStatus({
|
||||||
required this.taskId,
|
required this.taskId,
|
||||||
@ -43,6 +45,7 @@ class DriftUploadStatus {
|
|||||||
required this.fileSize,
|
required this.fileSize,
|
||||||
required this.networkSpeedAsString,
|
required this.networkSpeedAsString,
|
||||||
this.isFailed,
|
this.isFailed,
|
||||||
|
this.error,
|
||||||
});
|
});
|
||||||
|
|
||||||
DriftUploadStatus copyWith({
|
DriftUploadStatus copyWith({
|
||||||
@ -52,6 +55,7 @@ class DriftUploadStatus {
|
|||||||
int? fileSize,
|
int? fileSize,
|
||||||
String? networkSpeedAsString,
|
String? networkSpeedAsString,
|
||||||
bool? isFailed,
|
bool? isFailed,
|
||||||
|
String? error,
|
||||||
}) {
|
}) {
|
||||||
return DriftUploadStatus(
|
return DriftUploadStatus(
|
||||||
taskId: taskId ?? this.taskId,
|
taskId: taskId ?? this.taskId,
|
||||||
@ -60,12 +64,13 @@ class DriftUploadStatus {
|
|||||||
fileSize: fileSize ?? this.fileSize,
|
fileSize: fileSize ?? this.fileSize,
|
||||||
networkSpeedAsString: networkSpeedAsString ?? this.networkSpeedAsString,
|
networkSpeedAsString: networkSpeedAsString ?? this.networkSpeedAsString,
|
||||||
isFailed: isFailed ?? this.isFailed,
|
isFailed: isFailed ?? this.isFailed,
|
||||||
|
error: error ?? this.error,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'DriftUploadStatus(taskId: $taskId, filename: $filename, progress: $progress, fileSize: $fileSize, networkSpeedAsString: $networkSpeedAsString, isFailed: $isFailed)';
|
return 'DriftUploadStatus(taskId: $taskId, filename: $filename, progress: $progress, fileSize: $fileSize, networkSpeedAsString: $networkSpeedAsString, isFailed: $isFailed, error: $error)';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -77,7 +82,8 @@ class DriftUploadStatus {
|
|||||||
other.progress == progress &&
|
other.progress == progress &&
|
||||||
other.fileSize == fileSize &&
|
other.fileSize == fileSize &&
|
||||||
other.networkSpeedAsString == networkSpeedAsString &&
|
other.networkSpeedAsString == networkSpeedAsString &&
|
||||||
other.isFailed == isFailed;
|
other.isFailed == isFailed &&
|
||||||
|
other.error == error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -87,7 +93,8 @@ class DriftUploadStatus {
|
|||||||
progress.hashCode ^
|
progress.hashCode ^
|
||||||
fileSize.hashCode ^
|
fileSize.hashCode ^
|
||||||
networkSpeedAsString.hashCode ^
|
networkSpeedAsString.hashCode ^
|
||||||
isFailed.hashCode;
|
isFailed.hashCode ^
|
||||||
|
error.hashCode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,7 +254,23 @@ class DriftBackupNotifier extends StateNotifier<DriftBackupState> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
state = state.copyWith(uploadItems: {...state.uploadItems, taskId: currentItem.copyWith(isFailed: true)});
|
String? error;
|
||||||
|
final exception = update.exception;
|
||||||
|
if (exception != null && exception is TaskHttpException) {
|
||||||
|
final message = tryJsonDecode(exception.description)?['message'] as String?;
|
||||||
|
if (message != null) {
|
||||||
|
final responseCode = exception.httpResponseCode;
|
||||||
|
error = "${exception.exceptionType}, response code $responseCode: $message";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
error ??= update.exception?.toString();
|
||||||
|
|
||||||
|
state = state.copyWith(
|
||||||
|
uploadItems: {
|
||||||
|
...state.uploadItems,
|
||||||
|
taskId: currentItem.copyWith(isFailed: true, error: error),
|
||||||
|
},
|
||||||
|
);
|
||||||
_logger.fine("Upload failed for taskId: $taskId, exception: ${update.exception}");
|
_logger.fine("Upload failed for taskId: $taskId, exception: ${update.exception}");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user