@@ -136,6 +136,10 @@ function isConfigured() {
136136let gatewayProc = null ;
137137let gatewayStarting = null ;
138138
139+ // Debug breadcrumbs for common Railway failures (502 / "Application failed to respond").
140+ let lastGatewayError = null ;
141+ let lastGatewayExit = null ;
142+
139143function sleep ( ms ) {
140144 return new Promise ( ( r ) => setTimeout ( r , ms ) ) ;
141145}
@@ -194,12 +198,16 @@ async function startGateway() {
194198 } ) ;
195199
196200 gatewayProc . on ( "error" , ( err ) => {
197- console . error ( `[gateway] spawn error: ${ String ( err ) } ` ) ;
201+ const msg = `[gateway] spawn error: ${ String ( err ) } ` ;
202+ console . error ( msg ) ;
203+ lastGatewayError = msg ;
198204 gatewayProc = null ;
199205 } ) ;
200206
201207 gatewayProc . on ( "exit" , ( code , signal ) => {
202- console . error ( `[gateway] exited code=${ code } signal=${ signal } ` ) ;
208+ const msg = `[gateway] exited code=${ code } signal=${ signal } ` ;
209+ console . error ( msg ) ;
210+ lastGatewayExit = { code, signal, at : new Date ( ) . toISOString ( ) } ;
203211 gatewayProc = null ;
204212 } ) ;
205213}
@@ -209,10 +217,17 @@ async function ensureGatewayRunning() {
209217 if ( gatewayProc ) return { ok : true } ;
210218 if ( ! gatewayStarting ) {
211219 gatewayStarting = ( async ( ) => {
212- await startGateway ( ) ;
213- const ready = await waitForGatewayReady ( { timeoutMs : 20_000 } ) ;
214- if ( ! ready ) {
215- throw new Error ( "Gateway did not become ready in time" ) ;
220+ try {
221+ lastGatewayError = null ;
222+ await startGateway ( ) ;
223+ const ready = await waitForGatewayReady ( { timeoutMs : 20_000 } ) ;
224+ if ( ! ready ) {
225+ throw new Error ( "Gateway did not become ready in time" ) ;
226+ }
227+ } catch ( err ) {
228+ const msg = `[gateway] start failure: ${ String ( err ) } ` ;
229+ lastGatewayError = msg ;
230+ throw err ;
216231 }
217232 } ) ( ) . finally ( ( ) => {
218233 gatewayStarting = null ;
@@ -666,15 +681,24 @@ app.post("/setup/api/run", requireSetupAuth, async (req, res) => {
666681app . get ( "/setup/api/debug" , requireSetupAuth , async ( _req , res ) => {
667682 const v = await runCmd ( OPENCLAW_NODE , clawArgs ( [ "--version" ] ) ) ;
668683 const help = await runCmd ( OPENCLAW_NODE , clawArgs ( [ "channels" , "add" , "--help" ] ) ) ;
684+
669685 res . json ( {
670686 wrapper : {
671687 node : process . version ,
672688 port : PORT ,
689+ publicPortEnv : process . env . PORT || null ,
673690 stateDir : STATE_DIR ,
674691 workspaceDir : WORKSPACE_DIR ,
675- configPath : configPath ( ) ,
692+ configured : isConfigured ( ) ,
693+ configPathResolved : configPath ( ) ,
694+ configPathCandidates : typeof resolveConfigCandidates === "function" ? resolveConfigCandidates ( ) : null ,
695+ internalGatewayHost : INTERNAL_GATEWAY_HOST ,
696+ internalGatewayPort : INTERNAL_GATEWAY_PORT ,
697+ gatewayTarget : GATEWAY_TARGET ,
676698 gatewayTokenFromEnv : Boolean ( process . env . OPENCLAW_GATEWAY_TOKEN ?. trim ( ) ) ,
677699 gatewayTokenPersisted : fs . existsSync ( path . join ( STATE_DIR , "gateway.token" ) ) ,
700+ lastGatewayError,
701+ lastGatewayExit,
678702 railwayCommit : process . env . RAILWAY_GIT_COMMIT_SHA || null ,
679703 } ,
680704 openclaw : {
@@ -1014,7 +1038,15 @@ app.use(async (req, res) => {
10141038 try {
10151039 await ensureGatewayRunning ( ) ;
10161040 } catch ( err ) {
1017- return res . status ( 503 ) . type ( "text/plain" ) . send ( `Gateway not ready: ${ String ( err ) } ` ) ;
1041+ const hint = [
1042+ "Gateway not ready." ,
1043+ String ( err ) ,
1044+ lastGatewayError ? `\n${ lastGatewayError } ` : "" ,
1045+ "\nTroubleshooting:" ,
1046+ "- Visit /setup and check the Debug Console" ,
1047+ "- Visit /setup/api/debug for config + gateway diagnostics" ,
1048+ ] . join ( "\n" ) ;
1049+ return res . status ( 503 ) . type ( "text/plain" ) . send ( hint ) ;
10181050 }
10191051 }
10201052
0 commit comments