@@ -7,73 +7,149 @@ const sandboxTimeout = 10 * 60 * 1000
77export const maxDuration = 60
88
99export async function POST ( req : Request ) {
10- const {
11- fragment,
12- userID,
13- teamID,
14- accessToken,
15- } : {
16- fragment : FragmentSchema
17- userID : string | undefined
18- teamID : string | undefined
19- accessToken : string | undefined
20- } = await req . json ( )
10+ try {
11+ const {
12+ fragment,
13+ userID,
14+ teamID,
15+ accessToken,
16+ } : {
17+ fragment : FragmentSchema
18+ userID : string | undefined
19+ teamID : string | undefined
20+ accessToken : string | undefined
21+ } = await req . json ( )
2122
22- const sbx = await Sandbox . create ( fragment . template , {
23- metadata : {
24- template : fragment . template ,
25- userID : userID ?? '' ,
26- teamID : teamID ?? '' ,
27- } ,
28- timeoutMs : sandboxTimeout ,
29- ...( teamID && accessToken
30- ? {
31- headers : {
32- 'X-Supabase-Team' : teamID ,
33- 'X-Supabase-Token' : accessToken ,
34- } ,
35- }
36- : { } ) ,
37- } )
23+ if ( ! fragment ) {
24+ return new Response (
25+ JSON . stringify ( {
26+ error : 'Missing fragment data' ,
27+ type : 'validation_error'
28+ } ) ,
29+ { status : 400 , headers : { 'Content-Type' : 'application/json' } }
30+ )
31+ }
3832
39- if ( fragment . has_additional_dependencies ) {
40- await sbx . commands . run ( fragment . install_dependencies_command )
41- }
33+ if ( ! process . env . E2B_API_KEY ) {
34+ console . error ( 'E2B_API_KEY environment variable not found' )
35+ return new Response (
36+ JSON . stringify ( {
37+ error : 'Code execution service is not configured. Please check environment settings.' ,
38+ type : 'config_error'
39+ } ) ,
40+ { status : 503 , headers : { 'Content-Type' : 'application/json' } }
41+ )
42+ }
4243
43- if ( fragment . code && Array . isArray ( fragment . code ) ) {
44- fragment . code . forEach ( async ( file ) => {
45- await sbx . files . write ( file . file_path , file . file_content )
46- } )
47- } else {
48- await sbx . files . write ( fragment . file_path , fragment . code )
49- }
44+ let sbx
45+ try {
46+ sbx = await Sandbox . create ( fragment . template , {
47+ metadata : {
48+ template : fragment . template ,
49+ userID : userID ?? '' ,
50+ teamID : teamID ?? '' ,
51+ } ,
52+ timeoutMs : sandboxTimeout ,
53+ ...( teamID && accessToken
54+ ? {
55+ headers : {
56+ 'X-Supabase-Team' : teamID ,
57+ 'X-Supabase-Token' : accessToken ,
58+ } ,
59+ }
60+ : { } ) ,
61+ } )
62+ } catch ( e2bError : any ) {
63+ console . error ( 'E2B Sandbox creation failed:' , e2bError )
64+ return new Response (
65+ JSON . stringify ( {
66+ error : 'Failed to create sandbox environment. Please try again later.' ,
67+ type : 'sandbox_creation_error' ,
68+ details : e2bError . message
69+ } ) ,
70+ { status : 503 , headers : { 'Content-Type' : 'application/json' } }
71+ )
72+ }
73+
74+ try {
75+ if ( fragment . has_additional_dependencies ) {
76+ await sbx . commands . run ( fragment . install_dependencies_command )
77+ }
78+
79+ if ( fragment . code && Array . isArray ( fragment . code ) ) {
80+ await Promise . all ( fragment . code . map ( async ( file ) => {
81+ await sbx . files . write ( file . file_path , file . file_content )
82+ } ) )
83+ } else {
84+ } else if ( fragment . code !== null && fragment . code !== undefined ) {
85+ await sbx . files . write ( fragment . file_path , fragment . code )
86+ } else {
87+ return new Response (
88+ JSON . stringify ( {
89+ error : 'Missing code data' ,
90+ type : 'validation_error'
91+ } ) ,
92+ { status : 400 , headers : { 'Content-Type' : 'application/json' } }
93+ )
94+ }
95+
96+ if ( fragment . template === 'code-interpreter-v1' ) {
97+ const { logs, error, results } = await sbx . runCode ( fragment . code || '' )
5098
51- if ( fragment . template === 'code-interpreter-v1' ) {
52- const { logs, error, results } = await sbx . runCode ( fragment . code || '' )
99+ return new Response (
100+ JSON . stringify ( {
101+ sbxId : sbx ?. sandboxId ,
102+ template : fragment . template ,
103+ stdout : logs . stdout ,
104+ stderr : logs . stderr ,
105+ runtimeError : error ,
106+ cellResults : results ,
107+ } as ExecutionResultInterpreter ) ,
108+ { headers : { 'Content-Type' : 'application/json' } }
109+ )
110+ }
53111
112+ await sbx . commands . run ( fragment . install_dependencies_command , {
113+ envs : {
114+ PORT : ( fragment . port || 80 ) . toString ( ) ,
115+ } ,
116+ } )
117+
118+ return new Response (
119+ JSON . stringify ( {
120+ sbxId : sbx ?. sandboxId ,
121+ template : fragment . template ,
122+ url : `https://${ sbx ?. getHost ( fragment . port || 80 ) } ` ,
123+ } as ExecutionResultWeb ) ,
124+ { headers : { 'Content-Type' : 'application/json' } }
125+ )
126+ } catch ( executionError : any ) {
127+ console . error ( 'Sandbox execution error:' , executionError )
128+
129+ // Clean up sandbox on execution error
130+ try {
131+ await sbx ?. kill ( )
132+ } catch { }
133+
134+ return new Response (
135+ JSON . stringify ( {
136+ error : 'Code execution failed. There may be an error in your code or dependencies.' ,
137+ type : 'execution_error' ,
138+ details : executionError . message
139+ } ) ,
140+ { status : 500 , headers : { 'Content-Type' : 'application/json' } }
141+ )
142+ }
143+
144+ } catch ( error : any ) {
145+ console . error ( 'Sandbox API Error:' , error )
54146 return new Response (
55147 JSON . stringify ( {
56- sbxId : sbx ?. sandboxId ,
57- template : fragment . template ,
58- stdout : logs . stdout ,
59- stderr : logs . stderr ,
60- runtimeError : error ,
61- cellResults : results ,
62- } as ExecutionResultInterpreter ) ,
148+ error : 'An unexpected error occurred while setting up the sandbox.' ,
149+ type : 'unknown_error' ,
150+ details : error ?. message || 'Unknown error'
151+ } ) ,
152+ { status : 500 , headers : { 'Content-Type' : 'application/json' } }
63153 )
64154 }
65-
66- await sbx . commands . run ( fragment . install_dependencies_command , {
67- envs : {
68- PORT : ( fragment . port || 80 ) . toString ( ) ,
69- } ,
70- } )
71-
72- return new Response (
73- JSON . stringify ( {
74- sbxId : sbx ?. sandboxId ,
75- template : fragment . template ,
76- url : `https://${ sbx ?. getHost ( fragment . port || 80 ) } ` ,
77- } as ExecutionResultWeb ) ,
78- )
79155}
0 commit comments