+10
-73
src/api/machines.ts
+10
-73
src/api/machines.ts
···
1
-
import { type Context, Hono } from "hono";
2
-
import { Data, Effect, pipe } from "effect";
3
-
import { parseParams, parseQueryParams, presentation } from "./utils.ts";
1
+
import { Hono } from "hono";
2
+
import { Effect, pipe } from "effect";
3
+
import {
4
+
handleError,
5
+
parseParams,
6
+
parseQueryParams,
7
+
parseStartRequest,
8
+
presentation,
9
+
} from "./utils.ts";
4
10
import { getInstanceState } from "../mod.ts";
5
11
import { listInstances } from "../state.ts";
6
-
import {
7
-
type CommandError,
8
-
findVm,
9
-
killProcess,
10
-
StopCommandError,
11
-
updateToStopped,
12
-
VmNotFoundError,
13
-
} from "../subcommands/stop.ts";
12
+
import { findVm, killProcess, updateToStopped } from "../subcommands/stop.ts";
14
13
import {
15
14
buildQemuArgs,
16
15
createLogsDir,
17
16
setupFirmware,
18
17
startDetachedQemu,
19
18
} from "../subcommands/start.ts";
20
-
import { MachineParamsSchema } from "../types.ts";
21
-
22
-
class ParseRequestError extends Data.TaggedError("ParseRequestError")<{
23
-
cause?: unknown;
24
-
message: string;
25
-
}> {}
26
-
27
-
export const handleError = (
28
-
error:
29
-
| VmNotFoundError
30
-
| StopCommandError
31
-
| CommandError
32
-
| ParseRequestError
33
-
| Error,
34
-
c: Context,
35
-
) =>
36
-
Effect.sync(() => {
37
-
if (error instanceof VmNotFoundError) {
38
-
return c.json(
39
-
{ message: "VM not found", code: "VM_NOT_FOUND" },
40
-
404,
41
-
);
42
-
}
43
-
if (error instanceof StopCommandError) {
44
-
return c.json(
45
-
{
46
-
message: error.message ||
47
-
`Failed to stop VM ${error.vmName}`,
48
-
code: "STOP_COMMAND_ERROR",
49
-
},
50
-
500,
51
-
);
52
-
}
53
-
54
-
if (error instanceof ParseRequestError) {
55
-
return c.json(
56
-
{
57
-
message: error.message || "Failed to parse request body",
58
-
code: "PARSE_BODY_ERROR",
59
-
},
60
-
400,
61
-
);
62
-
}
63
-
64
-
return c.json(
65
-
{ message: error instanceof Error ? error.message : String(error) },
66
-
500,
67
-
);
68
-
});
69
-
70
-
const parseStartRequest = (c: Context) =>
71
-
Effect.tryPromise({
72
-
try: async () => {
73
-
const body = await c.req.json();
74
-
return MachineParamsSchema.parse(body);
75
-
},
76
-
catch: (error) =>
77
-
new ParseRequestError({
78
-
cause: error,
79
-
message: error instanceof Error ? error.message : String(error),
80
-
}),
81
-
});
82
19
83
20
const app = new Hono();
84
21
+68
-1
src/api/utils.ts
+68
-1
src/api/utils.ts
···
1
-
import { Effect } from "effect";
1
+
import { Data, Effect } from "effect";
2
2
import type { Context } from "hono";
3
+
import {
4
+
type CommandError,
5
+
StopCommandError,
6
+
VmNotFoundError,
7
+
} from "../subcommands/stop.ts";
8
+
import { MachineParamsSchema } from "../types.ts";
3
9
4
10
export const parseQueryParams = (c: Context) => Effect.succeed(c.req.query());
5
11
···
7
13
8
14
export const presentation = (c: Context) =>
9
15
Effect.flatMap((data) => Effect.succeed(c.json(data)));
16
+
17
+
export class ParseRequestError extends Data.TaggedError("ParseRequestError")<{
18
+
cause?: unknown;
19
+
message: string;
20
+
}> {}
21
+
22
+
export const handleError = (
23
+
error:
24
+
| VmNotFoundError
25
+
| StopCommandError
26
+
| CommandError
27
+
| ParseRequestError
28
+
| Error,
29
+
c: Context,
30
+
) =>
31
+
Effect.sync(() => {
32
+
if (error instanceof VmNotFoundError) {
33
+
return c.json(
34
+
{ message: "VM not found", code: "VM_NOT_FOUND" },
35
+
404,
36
+
);
37
+
}
38
+
if (error instanceof StopCommandError) {
39
+
return c.json(
40
+
{
41
+
message: error.message ||
42
+
`Failed to stop VM ${error.vmName}`,
43
+
code: "STOP_COMMAND_ERROR",
44
+
},
45
+
500,
46
+
);
47
+
}
48
+
49
+
if (error instanceof ParseRequestError) {
50
+
return c.json(
51
+
{
52
+
message: error.message || "Failed to parse request body",
53
+
code: "PARSE_BODY_ERROR",
54
+
},
55
+
400,
56
+
);
57
+
}
58
+
59
+
return c.json(
60
+
{ message: error instanceof Error ? error.message : String(error) },
61
+
500,
62
+
);
63
+
});
64
+
65
+
export const parseStartRequest = (c: Context) =>
66
+
Effect.tryPromise({
67
+
try: async () => {
68
+
const body = await c.req.json();
69
+
return MachineParamsSchema.parse(body);
70
+
},
71
+
catch: (error) =>
72
+
new ParseRequestError({
73
+
cause: error,
74
+
message: error instanceof Error ? error.message : String(error),
75
+
}),
76
+
});