64 lines
3.7 KiB
Dart
64 lines
3.7 KiB
Dart
/// 약속 (modular_sync #6 · F18): 복사 · 이동 · 동기화가 사용자에게 보이는 실패 글 - 예외 이름 ("ProcessException:") · Dart 의 영어 파일 오류
|
|
/// ("Cannot copy file") 를 빼고 화면 언어로. 입력: 예외 (와 원본 경로들), 출력: 글. 원래 글 ('$e') 은 부르는 쪽이 작업 기록에 남긴다.
|
|
/// 쓰는 곳: 복사 · 이동 작업 (copy_center) · 실시간 동기화 상태 (live_sync)
|
|
library;
|
|
|
|
import 'dart:io';
|
|
|
|
import '../core/file_ops.dart' show isSameOrInside;
|
|
import '../l10n/tr.dart';
|
|
|
|
/// 237: 사용자에게 보이는 실패 글 - "ProcessException:" 같은 예외 이름 · "Command:" 줄은 빼고 내용만.
|
|
/// 원래 글 ('$e') 은 작업 기록에 그대로 남긴다.
|
|
/// 245: 앱이 직접 할 때의 파일 오류 (Dart 의 "Cannot delete file" 등 영어) 는 화면 언어로. [sources] 안의 파일을 못 지웠으면
|
|
/// rsync 때 (215) 와 같은 글 - 이동에서 원본만 남은 것
|
|
String userErrorText(Object e, {List<String> sources = const []}) => switch (e) {
|
|
ProcessException(:final message) when message.isNotEmpty => message,
|
|
FileSystemException(:final message, :final path, :final osError) => [
|
|
_fileErrorText(message, path, sources),
|
|
if (path != null && path.isNotEmpty) path,
|
|
if (osError != null && osError.message.isNotEmpty) osError.message,
|
|
].join(' · '),
|
|
_ => '$e'.replaceFirst(RegExp(r'^\w*(Exception|Error)(\([^)]*\))?: '), ''),
|
|
};
|
|
|
|
String _fileErrorText(String message, String? path, List<String> sources) {
|
|
final m = message.toLowerCase();
|
|
if (m.startsWith('cannot delete') || m.startsWith('deletion failed')) {
|
|
final inSource = path != null && sources.any((s) => isSameOrInside(path, s));
|
|
return inSource
|
|
? tr('원본 파일을 지우지 못했습니다 (권한이 없거나 사용 중). 대상에는 복사됐고 원본은 남아 있습니다.')
|
|
: tr('지우지 못했습니다 (권한이 없거나 사용 중)');
|
|
}
|
|
if (m.startsWith('cannot copy')) return tr('파일을 복사하지 못했습니다');
|
|
if (m.startsWith('cannot rename')) return tr('옮기거나 이름을 바꾸지 못했습니다');
|
|
if (m.startsWith('cannot open') || m.startsWith('cannot read')) return tr('파일을 읽지 못했습니다');
|
|
if (m.startsWith('cannot create') || m.startsWith('creation failed') || m.startsWith('cannot write')) {
|
|
return tr('만들거나 쓰지 못했습니다');
|
|
}
|
|
return message;
|
|
}
|
|
|
|
/// 215: rsync 가 실패했을 때 보일 글 - 원본을 못 지웠으면 쉬운 말 한 줄, 그리고 오류 · 권한 줄을 끝쪽부터 (전송한 파일 이름이 아니라).
|
|
/// 예전에는 출력의 앞쪽 8줄이라 파일 이름만 보이고 "Permission denied" · "rsync error … (code 23)" 가 빠지기 쉬웠다
|
|
String rsyncFailureText(int code, List<String> errLines, List<String> allLines) {
|
|
final all = [...errLines, ...allLines];
|
|
final removeFailed = all.any((l) {
|
|
final x = l.toLowerCase();
|
|
return x.contains('failed to remove') || x.contains('cannot delete') || x.contains('unable to remove');
|
|
});
|
|
bool important(String l) {
|
|
final x = l.toLowerCase();
|
|
return x.contains('error') || x.contains('fail') || x.contains('denied') || x.contains('cannot') || x.contains('permission');
|
|
}
|
|
|
|
final picked = errLines.where(important).toList();
|
|
final lines = picked.isNotEmpty ? picked : (errLines.isNotEmpty ? errLines : allLines);
|
|
final tail = lines.length > 6 ? lines.sublist(lines.length - 6) : lines;
|
|
return [
|
|
if (removeFailed) tr('원본 파일을 지우지 못했습니다 (권한이 없거나 사용 중). 대상에는 복사됐고 원본은 남아 있습니다.'),
|
|
trf('rsync 종료 코드 {0}', [code]),
|
|
...tail,
|
|
].join('\n');
|
|
}
|