|
|
@@ -97,6 +97,29 @@ export function http(
|
|
|
headers.delete("content-encoding")
|
|
|
headers.delete("content-length")
|
|
|
|
|
|
+ // An upstream 5xx from a remote workspace sandbox arrives here as an opaque
|
|
|
+ // status — its real cause (and log line) live only inside the sandbox. Buffer
|
|
|
+ // the small error body, log it locally so it shows up in the host's log, and
|
|
|
+ // forward it unchanged (preserving content-type so the client can still parse
|
|
|
+ // the structured error, e.g. its `ref`).
|
|
|
+ if (response.status >= 500) {
|
|
|
+ const body = yield* response.text.pipe(Effect.catch(() => Effect.succeed("")))
|
|
|
+ const contentType = response.headers["content-type"] ?? "application/json"
|
|
|
+ headers.delete("content-type")
|
|
|
+ yield* Effect.logError("workspace proxy upstream error", {
|
|
|
+ url: url.toString(),
|
|
|
+ method: request.method,
|
|
|
+ status: response.status,
|
|
|
+ body: body.slice(0, 2000),
|
|
|
+ })
|
|
|
+ return HttpServerResponse.text(body, {
|
|
|
+ status: response.status,
|
|
|
+ statusText: statusText(response),
|
|
|
+ headers,
|
|
|
+ contentType,
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
return HttpServerResponse.stream(response.stream.pipe(Stream.catchCause(() => Stream.empty)), {
|
|
|
status: response.status,
|
|
|
statusText: statusText(response),
|