fix(workspaces): surface real error messages on failed workspace operations (#29167)
Signed-off-by: James Murdza <james@jamesmurdza.com>
This commit is contained in:
@@ -27,6 +27,16 @@ export class ApiWorkspaceWarpError extends Schema.ErrorClass<ApiWorkspaceWarpErr
|
||||
{ httpApiStatus: 400 },
|
||||
) {}
|
||||
|
||||
export class ApiWorkspaceCreateError extends Schema.ErrorClass<ApiWorkspaceCreateError>("WorkspaceCreateError")(
|
||||
{
|
||||
name: Schema.Literal("WorkspaceCreateError"),
|
||||
data: Schema.Struct({
|
||||
message: Schema.String,
|
||||
}),
|
||||
},
|
||||
{ httpApiStatus: 400 },
|
||||
) {}
|
||||
|
||||
export const WorkspacePaths = {
|
||||
adapters: `${root}/adapter`,
|
||||
list: root,
|
||||
@@ -64,7 +74,7 @@ export const WorkspaceApi = HttpApi.make("workspace")
|
||||
query: WorkspaceRoutingQuery,
|
||||
payload: CreatePayload,
|
||||
success: described(Workspace.Info, "Workspace created"),
|
||||
error: HttpApiError.BadRequest,
|
||||
error: [ApiWorkspaceCreateError, HttpApiError.BadRequest],
|
||||
}).annotateMerge(
|
||||
OpenApi.annotations({
|
||||
identifier: "experimental.workspace.create",
|
||||
|
||||
@@ -2,12 +2,12 @@ import { listAdapters } from "@/control-plane/adapters"
|
||||
import { Workspace } from "@/control-plane/workspace"
|
||||
import * as InstanceState from "@/effect/instance-state"
|
||||
import { Vcs } from "@/project/vcs"
|
||||
import { Effect } from "effect"
|
||||
import { HttpApiBuilder, HttpApiError } from "effect/unstable/httpapi"
|
||||
import { Cause, Effect } from "effect"
|
||||
import { HttpApiBuilder } from "effect/unstable/httpapi"
|
||||
import { InstanceHttpApi } from "../api"
|
||||
import { notFound } from "../errors"
|
||||
import { ApiVcsApplyError } from "../groups/instance"
|
||||
import { ApiWorkspaceWarpError, CreatePayload, WarpPayload } from "../groups/workspace"
|
||||
import { ApiWorkspaceCreateError, ApiWorkspaceWarpError, CreatePayload, WarpPayload } from "../groups/workspace"
|
||||
|
||||
export const workspaceHandlers = HttpApiBuilder.group(InstanceHttpApi, "workspace", (handlers) =>
|
||||
Effect.gen(function* () {
|
||||
@@ -30,7 +30,22 @@ export const workspaceHandlers = HttpApiBuilder.group(InstanceHttpApi, "workspac
|
||||
extra: ctx.payload.extra ?? null,
|
||||
projectID: instance.project.id,
|
||||
})
|
||||
.pipe(Effect.mapError(() => new HttpApiError.BadRequest({})))
|
||||
.pipe(
|
||||
Effect.catchCause((cause) => {
|
||||
// Plugin throws surface as defects (because EffectBridge.fromPromise uses Effect.promise),
|
||||
// bypassing Effect.mapError. Walk the cause to surface the real error to the client.
|
||||
const die = cause.reasons.find(Cause.isDieReason)
|
||||
const fail = cause.reasons.find(Cause.isFailReason)
|
||||
const reason: unknown = die?.defect ?? fail?.error
|
||||
const message = reason instanceof Error ? reason.message : "Workspace creation failed"
|
||||
return Effect.fail(
|
||||
new ApiWorkspaceCreateError({
|
||||
name: "WorkspaceCreateError",
|
||||
data: { message },
|
||||
}),
|
||||
)
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
const syncList = Effect.fn("WorkspaceHttpApi.syncList")(function* () {
|
||||
|
||||
Reference in New Issue
Block a user