@@ -5,53 +5,54 @@ import { iife } from "@/util/iife"
55import { NamedError } from "@opencode-ai/core/util/error"
66import * as Log from "@opencode-ai/core/util/log"
77import { Cause , Effect } from "effect"
8- import { HttpRouter , HttpServerError , HttpServerResponse } from "effect/unstable/http"
8+ import { HttpRouter , HttpServerError , HttpServerRespondable , HttpServerResponse } from "effect/unstable/http"
99
1010const log = Log . create ( { service : "server" } )
1111
1212// Keep typed HttpApi failures on their declared error path; this boundary only replaces defect-only empty 500s.
1313export const errorLayer = HttpRouter . middleware < { handles : unknown } > ( ) ( ( effect ) =>
1414 effect . pipe (
15- Effect . catchCauseIf (
16- ( cause ) => Cause . hasDies ( cause ) ,
17- ( cause ) => {
18- const error = Cause . squash ( cause )
19- if ( HttpServerResponse . isHttpServerResponse ( error ) ) return Effect . succeed ( error )
20- if ( HttpServerError . isHttpServerError ( error ) )
21- return HttpServerError . causeResponse ( cause ) . pipe ( Effect . map ( ( response ) => response [ 0 ] ) )
15+ Effect . catchCause ( ( cause ) => {
16+ const defect = cause . reasons . filter ( Cause . isDieReason ) . find ( ( reason ) => {
17+ if ( HttpServerResponse . isHttpServerResponse ( reason . defect ) ) return false
18+ if ( HttpServerError . isHttpServerError ( reason . defect ) ) return false
19+ if ( HttpServerRespondable . isRespondable ( reason . defect ) ) return false
20+ return true
21+ } )
22+ if ( ! defect ) return Effect . failCause ( cause )
2223
23- log . error ( "failed" , { error, cause : Cause . pretty ( cause ) } )
24+ const error = defect . defect
25+ log . error ( "failed" , { error, cause : Cause . pretty ( cause ) } )
2426
25- if ( error instanceof NamedError ) {
26- return Effect . succeed (
27- HttpServerResponse . jsonUnsafe ( error . toObject ( ) , {
28- status : iife ( ( ) => {
29- if ( error instanceof NotFoundError ) return 404
30- if ( error instanceof Provider . ModelNotFoundError ) return 400
31- if ( error . name === "ProviderAuthValidationFailed" ) return 400
32- if ( error . name . startsWith ( "Worktree" ) ) return 400
33- return 500
34- } ) ,
35- } ) ,
36- )
37- }
38- if ( error instanceof Session . BusyError ) {
39- return Effect . succeed (
40- HttpServerResponse . jsonUnsafe ( new NamedError . Unknown ( { message : error . message } ) . toObject ( ) , {
41- status : 400 ,
27+ if ( error instanceof NamedError ) {
28+ return Effect . succeed (
29+ HttpServerResponse . jsonUnsafe ( error . toObject ( ) , {
30+ status : iife ( ( ) => {
31+ if ( error instanceof NotFoundError ) return 404
32+ if ( error instanceof Provider . ModelNotFoundError ) return 400
33+ if ( error . name === "ProviderAuthValidationFailed" ) return 400
34+ if ( error . name . startsWith ( "Worktree" ) ) return 400
35+ return 500
4236 } ) ,
43- )
44- }
45-
37+ } ) ,
38+ )
39+ }
40+ if ( error instanceof Session . BusyError ) {
4641 return Effect . succeed (
47- HttpServerResponse . jsonUnsafe (
48- new NamedError . Unknown ( {
49- message : error instanceof Error && error . stack ? error . stack : String ( error ) ,
50- } ) . toObject ( ) ,
51- { status : 500 } ,
52- ) ,
42+ HttpServerResponse . jsonUnsafe ( new NamedError . Unknown ( { message : error . message } ) . toObject ( ) , {
43+ status : 400 ,
44+ } ) ,
5345 )
54- } ,
55- ) ,
46+ }
47+
48+ return Effect . succeed (
49+ HttpServerResponse . jsonUnsafe (
50+ new NamedError . Unknown ( {
51+ message : error instanceof Error && error . stack ? error . stack : String ( error ) ,
52+ } ) . toObject ( ) ,
53+ { status : 500 } ,
54+ ) ,
55+ )
56+ } ) ,
5657 ) ,
5758) . layer
0 commit comments