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
|
|
@ -85,6 +85,30 @@ void showFaiErrorSnack(
|
|||
);
|
||||
}
|
||||
|
||||
/// Surface a failed external-process result (daemon start, binary
|
||||
/// probe, file-open) as a copyable error snack. The `ok/stdout/stderr`
|
||||
/// record these actions return is not a thrown error, so call sites used
|
||||
/// to drop it into a raw `SnackBar(Text(...))` — uncopyable, the exact
|
||||
/// thing the operator needs to paste back. This joins stderr + stdout
|
||||
/// into one selectable, one-tap-copyable, logged message.
|
||||
void showFaiProcessError(
|
||||
BuildContext context,
|
||||
String source,
|
||||
String stdout,
|
||||
String stderr, {
|
||||
String? title,
|
||||
}) {
|
||||
final detail = [stderr.trim(), stdout.trim()]
|
||||
.where((s) => s.isNotEmpty)
|
||||
.join('\n\n');
|
||||
showFaiErrorSnack(
|
||||
context,
|
||||
source,
|
||||
detail.isEmpty ? 'process exited non-zero (no output)' : detail,
|
||||
title: title,
|
||||
);
|
||||
}
|
||||
|
||||
/// Show [error] as a centered modal dialog. Use this when the
|
||||
/// failure blocks meaningful interaction (auth missing, hub
|
||||
/// unreachable) — a SnackBar would be too easy to dismiss.
|
||||
|
|
|
|||
|
|
@ -902,7 +902,18 @@ class HubService {
|
|||
.catchError((_) => <PendingApprovalEntry>[]),
|
||||
_client.verifyEventChain().catchError((_) => VerifyEventChainResponse()),
|
||||
_client.listServices().catchError((_) => <DeclaredService>[]),
|
||||
_client.checkUpdate().catchError((_) => CheckUpdateResponse()),
|
||||
// checkUpdate does a live manifest fetch (server-side 8s timeout).
|
||||
// The other five are local-socket RPCs that return in ms, so cap
|
||||
// this one tightly — otherwise it alone gates the whole Diagnose
|
||||
// page open. A timeout reads as "release host unreachable", which
|
||||
// the UI already renders as an offline banner, not an error.
|
||||
_client
|
||||
.checkUpdate()
|
||||
.timeout(
|
||||
const Duration(seconds: 2),
|
||||
onTimeout: () => CheckUpdateResponse(),
|
||||
)
|
||||
.catchError((_) => CheckUpdateResponse()),
|
||||
_client.daemonPaths().catchError((_) => DaemonPathsResponse()),
|
||||
]);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue