map POSIX errno to actionable IPC error kinds (T-79)
pane.spawn (via PtyException.errno) and editor.open (via FileSystemException.osError.errorCode) now route ENOENT to not_found, EACCES/EPERM to user_error with a permissions hint, EISDIR/ENOTDIR/EEXIST to distinct user-error/conflict, and EMFILE/ENFILE to tool_error with a "fd limit hit" hint. The mapping lives in lib/src/ipc/errno_mapping.dart so other handlers can adopt the same surface as they pick up errno-bearing failures. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -12,9 +12,11 @@ library;
|
||||
import 'dart:convert';
|
||||
|
||||
import '../ipc/envelope.dart';
|
||||
import '../ipc/errno_mapping.dart';
|
||||
import '../ipc/schema_v1.dart';
|
||||
import '../panes/pane.dart';
|
||||
import '../panes/registry.dart';
|
||||
import '../pty/errors.dart';
|
||||
import 'dispatcher.dart';
|
||||
|
||||
void registerPaneCommands(DaemonDispatcher d, PaneRegistry registry) {
|
||||
@@ -84,6 +86,26 @@ Future<IpcResponse> _spawn(IpcRequest req, PaneRegistry registry) async {
|
||||
title: args['title'] as String?,
|
||||
);
|
||||
return IpcResponse.ok(id: req.id, data: pane.toJson());
|
||||
} on PtyException catch (e) {
|
||||
final errno = e.errno;
|
||||
if (errno != null) {
|
||||
return IpcResponse.err(
|
||||
id: req.id,
|
||||
error: errnoToIpcError(
|
||||
errno: errno,
|
||||
op: 'pane.spawn',
|
||||
target: argv.isNotEmpty ? argv.first : null,
|
||||
),
|
||||
);
|
||||
}
|
||||
return IpcResponse.err(
|
||||
id: req.id,
|
||||
error: IpcError(
|
||||
code: IpcExitCode.toolError,
|
||||
kind: IpcErrorKind.toolError,
|
||||
message: 'pane.spawn failed: ${e.message}',
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
return IpcResponse.err(
|
||||
id: req.id,
|
||||
|
||||
Reference in New Issue
Block a user