[hotfix] #342 v0.4.2 — ChatScreen SafeArea + LLM 에러 진단 노출
Fix - ChatScreen body 를 SafeArea(top: false) 로 감쌈. Android edge-to-edge 모드에서 시스템 nav bar 가 입력창을 덮던 문제 해결. Dev (#342) - userTurn catch 블록이 e.toString() + stack trace 를 error 상태에 저장. - 빨간 에러 컨테이너를 SingleChildScrollView + SelectableText (monospace) + 최대 화면 1/3 높이 제약. 스크롤 + 복사 가능. release 빌드에서도 full stack 노출 (#342 종료 후 follow-up 으로 좁힘). 테스트: chat_session_controller_test 8/8 통과. APK: app-release.apk 301.0MB SHA 02a5d1c8. Refs #342
This commit is contained in:
@@ -3,6 +3,14 @@
|
||||
본 프로젝트의 모든 의미있는 변경은 본 파일에 기록한다.
|
||||
형식: [Keep a Changelog](https://keepachangelog.com/) · 버전: [SemVer](https://semver.org/).
|
||||
|
||||
## [0.4.2] — 2026-06-15 (hotfix, dev)
|
||||
|
||||
### Fixed (Redmine #342)
|
||||
- **ChatScreen 하단 잘림** — Android edge-to-edge 모드에서 시스템 nav bar (3-button / gesture handle) 가 입력창을 덮던 문제. `Scaffold.body` 를 `SafeArea(top: false, …)` 로 감쌈. AppBar 가 이미 top inset 처리하므로 top 만 false.
|
||||
|
||||
### Dev
|
||||
- **LLM 실패 빨간 배너에 full message + stack trace** — 단말 진단을 위해 release 빌드에서도 노출. `LLM 응답 실패: <Type>\n<message>\n--- STACK ---\n<stack>` 형식. SelectableText + monospace + 최대 화면 1/3 높이 + scroll. 사용자 친화 메시지로 좁히는 작업은 #342 종료 후 follow-up.
|
||||
|
||||
## [0.4.1] — 2026-06-15
|
||||
|
||||
### Added — ChatScreen LLM warm-up (Redmine #311, follow-up of #260)
|
||||
|
||||
@@ -206,12 +206,16 @@ class ChatSessionController extends StateNotifier<ChatSessionState> {
|
||||
clearStreamingText: true,
|
||||
error: '도구 호출 루프가 너무 길어 중단했습니다.',
|
||||
);
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
if (!mounted) return;
|
||||
// 개발 단계 (#342) — 실 단말 진단을 위해 release 빌드에서도 full
|
||||
// message + stack 노출. 사용자 친화 메시지로 다시 좁히는 작업은
|
||||
// #342 종료 후 follow-up.
|
||||
final detail = 'LLM 응답 실패: ${e.runtimeType}\n$e\n\n--- STACK ---\n$st';
|
||||
state = state.copyWith(
|
||||
isStreaming: false,
|
||||
clearStreamingText: true,
|
||||
error: 'LLM 응답 실패: ${e.runtimeType}',
|
||||
error: detail,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,10 +76,16 @@ class _ChatScreenState extends ConsumerState<ChatScreen> {
|
||||
),
|
||||
],
|
||||
),
|
||||
body: depsAsync.when(
|
||||
loading: () => const Center(child: CircularProgressIndicator()),
|
||||
error: (e, _) => Center(child: Text('초기화 실패: $e')),
|
||||
data: (_) => _buildBody(context),
|
||||
// Android edge-to-edge: 시스템 nav bar (3-button / gesture handle) 가
|
||||
// 입력창을 가리지 않도록 SafeArea 로 감싼다. AppBar 가 이미 top inset
|
||||
// 을 처리하므로 top 만 false.
|
||||
body: SafeArea(
|
||||
top: false,
|
||||
child: depsAsync.when(
|
||||
loading: () => const Center(child: CircularProgressIndicator()),
|
||||
error: (e, _) => Center(child: Text('초기화 실패: $e')),
|
||||
data: (_) => _buildBody(context),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -105,14 +111,23 @@ class _ChatScreenState extends ConsumerState<ChatScreen> {
|
||||
children: [
|
||||
if (warmup is ChatWarmupFailed) _WarmupErrorBanner(warmup: warmup),
|
||||
if (state.error != null)
|
||||
// #342 dev — 단말에서 원인 진단을 위해 stack 까지 노출되는 케이스를
|
||||
// 위해 multi-line + scrollable + selectable. 높이는 화면의 1/3 까지만.
|
||||
Container(
|
||||
width: double.infinity,
|
||||
color: theme.colorScheme.errorContainer,
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: Text(
|
||||
state.error!,
|
||||
style: TextStyle(
|
||||
color: theme.colorScheme.onErrorContainer,
|
||||
constraints: BoxConstraints(
|
||||
maxHeight: MediaQuery.of(context).size.height / 3,
|
||||
),
|
||||
child: SingleChildScrollView(
|
||||
child: SelectableText(
|
||||
state.error!,
|
||||
style: TextStyle(
|
||||
color: theme.colorScheme.onErrorContainer,
|
||||
fontFamily: 'monospace',
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
name: life_helper
|
||||
description: "Huberman + Atomic Habits + Tiny Habits + If-Then. Local-first habit/checklist/todo."
|
||||
publish_to: 'none'
|
||||
version: 0.4.1+5
|
||||
version: 0.4.2+6
|
||||
|
||||
environment:
|
||||
sdk: ^3.12.2
|
||||
|
||||
Reference in New Issue
Block a user