@@ -72,6 +72,57 @@ const PASSPORT_FUNCTIONS = {
7272 } ,
7373} ;
7474
75+ function getHttpErrorSummary ( err : unknown ) : {
76+ status ?: number ;
77+ fullUrl ?: string ;
78+ traceId ?: string ;
79+ requestId ?: string ;
80+ cfRay ?: string ;
81+ } {
82+ const e : any = err as any ;
83+ const status : number | undefined = e ?. response ?. status ;
84+ const url : string | undefined = e ?. config ?. url ;
85+ const baseURL : string | undefined = e ?. config ?. baseURL ;
86+ let fullUrl = typeof url === 'string' && typeof baseURL === 'string' && ! / ^ h t t p s ? : \/ \/ / i. test ( url )
87+ ? `${ baseURL } ${ url } `
88+ : url ;
89+
90+ // Remove query parameters to avoid exposing sensitive data (tokens, API keys, etc.)
91+ if ( typeof fullUrl === 'string' ) {
92+ const queryIndex = fullUrl . indexOf ( '?' ) ;
93+ if ( queryIndex !== - 1 ) {
94+ fullUrl = fullUrl . substring ( 0 , queryIndex ) ;
95+ }
96+ }
97+
98+ const headers : Record < string , string > | undefined = e ?. response ?. headers ;
99+ const traceId = headers ?. [ 'x-amzn-trace-id' ] ?? headers ?. [ 'x-trace-id' ] ;
100+ const requestId = headers ?. [ 'x-amzn-requestid' ]
101+ ?? headers ?. [ 'x-amzn-request-id' ]
102+ ?? headers ?. [ 'x-request-id' ] ;
103+ const cfRay = headers ?. [ 'cf-ray' ] ;
104+
105+ return {
106+ status,
107+ fullUrl,
108+ traceId,
109+ requestId,
110+ cfRay,
111+ } ;
112+ }
113+
114+ function parseHttpStatusSuffix ( message : string ) : { status ?: number ; url ?: string } {
115+ // Matches our existing suffix formats like:
116+ // "... [httpStatus=500 url=https://...]" or
117+ // "... [httpStatus=500 url=https://... trace=... ...]"
118+ const m = message . match ( / \[ h t t p S t a t u s = ( [ ^ \s \] ] + ) \s + u r l = ( [ ^ \s \] ] + ) [ ^ \] ] * \] / ) ;
119+ if ( ! m ) return { } ;
120+ const statusStr = m [ 1 ] ;
121+ const url = m [ 2 ] ;
122+ const status = statusStr && / ^ [ 0 - 9 ] + $ / . test ( statusStr ) ? Number ( statusStr ) : undefined ;
123+ return { status, url } ;
124+ }
125+
75126// To notify game engine that this file is loaded
76127const initRequest = 'init' ;
77128const initRequestId = '1' ;
@@ -126,27 +177,31 @@ type VersionInfo = {
126177
127178const callbackToGame = ( data : CallbackData ) => {
128179 const message = JSON . stringify ( data ) ;
129- console . log ( `callbackToGame: ${ message } ` ) ;
130- if ( typeof window . ue !== 'undefined' ) {
131- if ( typeof window . ue . jsconnector === 'undefined' ) {
132- const unrealError = 'Unreal JSConnector not defined' ;
133- console . error ( unrealError ) ;
134- throw new Error ( unrealError ) ;
135- } else {
180+
181+ try {
182+ if ( typeof window . ue !== 'undefined' ) {
183+ if ( typeof window . ue . jsconnector === 'undefined' ) {
184+ const unrealError = 'Unreal JSConnector not defined' ;
185+ console . error ( '[GAME-BRIDGE]' , unrealError ) ;
186+ throw new Error ( unrealError ) ;
187+ }
136188 window . ue . jsconnector . sendtogame ( message ) ;
189+ } else if ( typeof blu_event !== 'undefined' ) {
190+ blu_event ( 'sendtogame' , message ) ;
191+ } else if ( typeof UnityPostMessage !== 'undefined' ) {
192+ UnityPostMessage ( message ) ;
193+ } else if ( typeof window . Unity !== 'undefined' ) {
194+ window . Unity . call ( message ) ;
195+ } else if ( typeof window . uwb !== 'undefined' ) {
196+ window . uwb . ExecuteJsMethod ( 'callback' , message ) ;
197+ } else {
198+ const gameBridgeError = 'No available game callbacks to call from ImmutableSDK game-bridge' ;
199+ console . error ( '[GAME-BRIDGE]' , gameBridgeError ) ;
200+ throw new Error ( gameBridgeError ) ;
137201 }
138- } else if ( typeof blu_event !== 'undefined' ) {
139- blu_event ( 'sendtogame' , message ) ;
140- } else if ( typeof UnityPostMessage !== 'undefined' ) {
141- UnityPostMessage ( message ) ;
142- } else if ( typeof window . Unity !== 'undefined' ) {
143- window . Unity . call ( message ) ;
144- } else if ( typeof window . uwb !== 'undefined' ) {
145- window . uwb . ExecuteJsMethod ( 'callback' , message ) ;
146- } else {
147- const gameBridgeError = 'No available game callbacks to call from ImmutableSDK game-bridge' ;
148- console . error ( gameBridgeError ) ;
149- throw new Error ( gameBridgeError ) ;
202+ } catch ( error ) {
203+ console . error ( '[GAME-BRIDGE] Error in callbackToGame:' , error ) ;
204+ throw error ;
150205 }
151206} ;
152207
@@ -224,9 +279,9 @@ window.callFunction = async (jsonData: string) => {
224279 const request = JSON . parse ( data ) ;
225280 const redirect : string | null = request ?. redirectUri ;
226281 const logoutMode : 'silent' | 'redirect' = request ?. isSilentLogout === true ? 'silent' : 'redirect' ;
282+
227283 if ( ! passportClient || passportInitData !== data ) {
228284 passportInitData = data ;
229- console . log ( `Connecting to ${ request . environment } environment` ) ;
230285
231286 let passportConfig : passport . PassportModuleConfiguration ;
232287
@@ -259,6 +314,8 @@ window.callFunction = async (jsonData: string) => {
259314 chainID : 5 ,
260315 coreContractAddress : '0xd05323731807A35599BF9798a1DE15e89d6D6eF1' ,
261316 registrationContractAddress : '0x7EB840223a3b1E0e8D54bF8A6cd83df5AFfC88B2' ,
317+ sdkVersion : sdkVersionTag ,
318+ baseConfig,
262319 } ) ,
263320 } ,
264321 } ) ,
@@ -283,9 +340,15 @@ window.callFunction = async (jsonData: string) => {
283340 } ;
284341 }
285342
286- passportClient = new passport . Passport ( passportConfig ) ;
287- trackDuration ( moduleName , 'initialisedPassport' , mt ( markStart ) ) ;
343+ try {
344+ passportClient = new passport . Passport ( passportConfig ) ;
345+ trackDuration ( moduleName , 'initialisedPassport' , mt ( markStart ) ) ;
346+ } catch ( initError ) {
347+ console . error ( '[GAME-BRIDGE] Error creating Passport client:' , initError ) ;
348+ throw initError ;
349+ }
288350 }
351+
289352 callbackToGame ( {
290353 responseFor : fxName ,
291354 requestId,
@@ -805,6 +868,41 @@ window.callFunction = async (jsonData: string) => {
805868 wrappedError = error ;
806869 }
807870
871+ // Make endpoint visible in Unity Output for debugging (CI logs don't include JS console).
872+ const {
873+ status,
874+ fullUrl,
875+ traceId,
876+ requestId : httpRequestId ,
877+ cfRay,
878+ } = getHttpErrorSummary ( error ) ;
879+ if (
880+ fxName === PASSPORT_FUNCTIONS . imx . registerOffchain
881+ && wrappedError instanceof Error
882+ ) {
883+ // Some upstream errors embed "[httpStatus=... url=...]" only in the message string
884+ // without preserving axios-like fields. Parse what we can so we can still enrich.
885+ const parsed = parseHttpStatusSuffix ( wrappedError . message ) ;
886+ const effectiveStatus = status ?? parsed . status ;
887+ const effectiveUrl = fullUrl ?? parsed . url ;
888+ const suffix = ` [httpStatus=${ effectiveStatus ?? 'unknown' } `
889+ + ` url=${ effectiveUrl ?? 'unknown' } `
890+ + ` trace=${ traceId ?? 'unknown' } `
891+ + ` reqId=${ httpRequestId ?? 'unknown' } `
892+ + ` cfRay=${ cfRay ?? 'unknown' } ]` ;
893+ // If a previous layer already added a minimal suffix like:
894+ // "... [httpStatus=500 url=...]"
895+ // upgrade it to include trace/reqId/resp instead of skipping.
896+ if ( wrappedError . message . includes ( '[httpStatus=' ) ) {
897+ if ( ! wrappedError . message . includes ( 'trace=' ) ) {
898+ const upgraded = wrappedError . message . replace ( / \[ h t t p S t a t u s = [ ^ \] ] * \] / g, suffix . trim ( ) ) ;
899+ wrappedError = new Error ( upgraded ) ;
900+ }
901+ } else {
902+ wrappedError = new Error ( `${ wrappedError . message } ${ suffix } ` ) ;
903+ }
904+ }
905+
808906 const errorType = error instanceof passport . PassportError
809907 ? error ?. type
810908 : undefined ;
@@ -827,7 +925,10 @@ window.callFunction = async (jsonData: string) => {
827925 responseFor : fxName ,
828926 requestId,
829927 success : false ,
830- error : error ?. message !== null && error ?. message !== undefined ? error . message : 'Error' ,
928+ // IMPORTANT: return the wrapped error message so we include extra HTTP diagnostics
929+ // (httpStatus/url/trace/reqId/resp) in Unity CI logs.
930+ error : wrappedError ?. message
931+ ?? ( error ?. message !== null && error ?. message !== undefined ? error . message : 'Error' ) ,
831932 errorType : error instanceof passport . PassportError ? error ?. type : null ,
832933 } ) ;
833934 }
0 commit comments