Preserve courses with pending rooms and report precise graduate import errors
This commit is contained in:
@@ -174,6 +174,8 @@ class SchoolSession extends ChangeNotifier {
|
||||
bool _routeClosed = false;
|
||||
int _pollsLeft = 0;
|
||||
int? _probeGeneration;
|
||||
UnsupportedSchoolLayout? _lastLayoutFailure;
|
||||
int? _layoutFailureGeneration;
|
||||
SchoolConnectionState connectionState = SchoolConnectionState.signedOut;
|
||||
bool _loading = false,
|
||||
hasOpened = false,
|
||||
@@ -334,9 +336,16 @@ class SchoolSession extends ChangeNotifier {
|
||||
String get _findingMessage => requestingExams ? '正在查找考试安排,请稍候' : '正在查找课表,请稍候';
|
||||
void _armTimeout() {
|
||||
_timeout?.cancel();
|
||||
_timeout = Timer(
|
||||
const Duration(seconds: 45),
|
||||
() => _failure('查找超时,请检查学校页面后重试。已有数据保持不变。', code: 'read_timeout'),
|
||||
_timeout = Timer(const Duration(seconds: 45), _finishReadFailure);
|
||||
}
|
||||
|
||||
void _finishReadFailure() {
|
||||
final error = _layoutFailureGeneration == _pageGeneration
|
||||
? _lastLayoutFailure
|
||||
: null;
|
||||
_failure(
|
||||
error == null ? '查找超时,请检查学校页面后重试。已有数据保持不变。' : '课表读取未完成:$error',
|
||||
code: error?.code ?? 'read_timeout',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -396,7 +405,7 @@ class SchoolSession extends ChangeNotifier {
|
||||
}
|
||||
_poll?.cancel();
|
||||
if (_pollsLeft-- <= 0) {
|
||||
if (finding) _failure('查找超时,请检查学校页面后重试。已有数据保持不变。', code: 'read_timeout');
|
||||
if (finding) _finishReadFailure();
|
||||
return;
|
||||
}
|
||||
_poll = Timer(const Duration(milliseconds: 750), () {
|
||||
@@ -500,6 +509,8 @@ class SchoolSession extends ChangeNotifier {
|
||||
// gets only its recognized fragment with the canonical table path.
|
||||
final draft = await _reader.read(_target, () async => page.html);
|
||||
if (!hasOpened || generation != _pageGeneration) return;
|
||||
_lastLayoutFailure = null;
|
||||
_layoutFailureGeneration = null;
|
||||
if (draft.schoolTerm != selectedTerm) {
|
||||
DiagnosticLog.instance.add(
|
||||
'term_mismatch',
|
||||
@@ -528,11 +539,24 @@ class SchoolSession extends ChangeNotifier {
|
||||
notifyListeners();
|
||||
return;
|
||||
} catch (error) {
|
||||
if (generation != _pageGeneration) return;
|
||||
if (error is UnsupportedSchoolLayout) {
|
||||
_lastLayoutFailure = error;
|
||||
_layoutFailureGeneration = generation;
|
||||
message =
|
||||
'课表暂未识别:${error.description}。正在等待页面加载完整;若仍失败,请在反馈中附带学校HTML和日志。';
|
||||
}
|
||||
DiagnosticLog.instance.add(
|
||||
'school_parse_rejected',
|
||||
fields: {
|
||||
'school': 'graduate',
|
||||
'code': error.runtimeType.toString(),
|
||||
'code': error is UnsupportedSchoolLayout
|
||||
? error.code
|
||||
: error.runtimeType.toString(),
|
||||
if (error is UnsupportedSchoolLayout && error.row != null)
|
||||
'row': error.row,
|
||||
if (error is UnsupportedSchoolLayout && error.column != null)
|
||||
'column': error.column,
|
||||
},
|
||||
);
|
||||
if (generation != _pageGeneration) return;
|
||||
@@ -595,6 +619,7 @@ class SchoolSession extends ChangeNotifier {
|
||||
liveUrl != uri.toString()) {
|
||||
throw UnsupportedSchoolLayout();
|
||||
}
|
||||
UnsupportedSchoolLayout? rejected;
|
||||
for (final page in evidence.pages) {
|
||||
if (page.kind != 'timetable') continue;
|
||||
SchoolPageDiagnostic.instance.remember(page.html, page.url);
|
||||
@@ -608,11 +633,12 @@ class SchoolSession extends ChangeNotifier {
|
||||
}
|
||||
if (draft.schoolTerm != selectedTerm) continue;
|
||||
return draft;
|
||||
} on UnsupportedSchoolLayout {
|
||||
} on UnsupportedSchoolLayout catch (error) {
|
||||
if (generation != _pageGeneration) rethrow;
|
||||
rejected = error;
|
||||
}
|
||||
}
|
||||
throw UnsupportedSchoolLayout();
|
||||
throw rejected ?? const UnsupportedSchoolLayout(code: 'table_missing');
|
||||
}
|
||||
|
||||
Future<void> readCurrentPage() async {
|
||||
|
||||
Reference in New Issue
Block a user