fix(studio): audit batch — debug.echo install, copyable errors, fast Diagnose
From a live-test audit:
- Install via the flow-editor 'Fix' sent 'debug.echo@^0' (version
constraint included) as the install source; the hub resolves by bare
name so it missed ('no store entry for debug.echo@^0'). Strip the
@<constraint> like the Store page does — debug.echo now installs.
- Errors the operator could not copy: route the daemon-start failure
(its stderr!), the flow-editor install failure and the federation
issue failure through showFaiErrorSnack / a new showFaiProcessError
helper, so every error is selectable, one-tap copyable and logged.
- Diagnose page opened slowly because doctor() Future.wait-ed on a live
manifest fetch (8s server timeout); cap that one check at 2s so the
page no longer waits on the network.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
This commit is contained in:
parent
ee4a0f6c62
commit
5f56abcf5f
5 changed files with 85 additions and 30 deletions
|
|
@ -9,6 +9,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter/services.dart';
|
||||
|
||||
import 'data/chain_log.dart';
|
||||
import 'data/error_presentation.dart';
|
||||
import 'data/hub.dart';
|
||||
import 'data/system_actions.dart';
|
||||
import 'data/theme_plugin.dart';
|
||||
|
|
@ -270,14 +271,21 @@ class StudioShellState extends State<StudioShell> {
|
|||
final l = AppLocalizations.of(context)!;
|
||||
final r = await SystemActions.chainDaemon(['start']);
|
||||
if (!mounted) return;
|
||||
final detail = r.stderr.trim().isEmpty ? r.stdout.trim() : r.stderr.trim();
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
r.ok ? l.daemonStartRequested : l.daemonStartFailed(detail),
|
||||
),
|
||||
),
|
||||
);
|
||||
if (r.ok) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text(l.daemonStartRequested)),
|
||||
);
|
||||
} else {
|
||||
// Surface the daemon's stderr/stdout as a copyable error — this
|
||||
// is the message the operator most often needs to paste back.
|
||||
showFaiProcessError(
|
||||
context,
|
||||
'daemon.start',
|
||||
r.stdout,
|
||||
r.stderr,
|
||||
title: l.daemonStartFailed(''),
|
||||
);
|
||||
}
|
||||
// Probe again shortly so the UI flips to "connected" without
|
||||
// waiting for the next 5 s tick.
|
||||
Future.delayed(const Duration(seconds: 1), _checkHealth);
|
||||
|
|
@ -690,14 +698,21 @@ class _SidebarState extends State<_Sidebar>
|
|||
final l = AppLocalizations.of(context)!;
|
||||
final r = await SystemActions.chainDaemon(['start']);
|
||||
if (!context.mounted) return;
|
||||
final detail = r.stderr.trim().isEmpty ? r.stdout.trim() : r.stderr.trim();
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
r.ok ? l.daemonStartRequested : l.daemonStartFailed(detail),
|
||||
),
|
||||
),
|
||||
);
|
||||
if (r.ok) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text(l.daemonStartRequested)),
|
||||
);
|
||||
} else {
|
||||
// Surface the daemon's stderr/stdout as a copyable error — this
|
||||
// is the message the operator most often needs to paste back.
|
||||
showFaiProcessError(
|
||||
context,
|
||||
'daemon.start',
|
||||
r.stdout,
|
||||
r.stderr,
|
||||
title: l.daemonStartFailed(''),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue