@@ -793,15 +793,123 @@ export class ApiBlockHandler implements BlockHandler {
793793 throw new Error ( `Tool not found: ${ block . config . tool } ` )
794794 }
795795
796- const result = await executeTool ( block . config . tool , {
797- ...inputs ,
798- _context : { workflowId : context . workflowId } ,
799- } )
800- if ( ! result . success ) {
801- throw new Error ( result . error || `API request failed with no error message` )
796+ // Early return with empty success response if URL is not provided or empty
797+ if ( tool . name && tool . name . includes ( 'HTTP' ) && ( ! inputs . url || inputs . url . trim ( ) === '' ) ) {
798+ return { response : { content : '' , success : true } }
802799 }
803800
804- return { response : result . output }
801+ // Pre-validate common HTTP request issues to provide better error messages
802+ if ( tool . name && tool . name . includes ( 'HTTP' ) && inputs . url ) {
803+ // Check for missing protocol
804+ if ( ! inputs . url . match ( / ^ h t t p s ? : \/ \/ / i) ) {
805+ throw new Error (
806+ `Invalid URL: "${ inputs . url } " - URL must include protocol (try "https://${ inputs . url } ")`
807+ ) ;
808+ }
809+
810+ // Detect other common URL issues
811+ try {
812+ new URL ( inputs . url ) ;
813+ } catch ( e : any ) {
814+ throw new Error ( `Invalid URL format: "${ inputs . url } " - ${ e . message } ` ) ;
815+ }
816+ }
817+
818+ try {
819+ const result = await executeTool ( block . config . tool , {
820+ ...inputs ,
821+ _context : { workflowId : context . workflowId } ,
822+ } )
823+
824+ if ( ! result . success ) {
825+ const errorDetails = [ ] ;
826+
827+ // Add request details to error message
828+ if ( inputs . url ) errorDetails . push ( `URL: ${ inputs . url } ` ) ;
829+ if ( inputs . method ) errorDetails . push ( `Method: ${ inputs . method } ` ) ;
830+
831+ // Add response details
832+ if ( result . error ) errorDetails . push ( `Error: ${ result . error } ` ) ;
833+ if ( result . output ?. status ) errorDetails . push ( `Status: ${ result . output . status } ` ) ;
834+ if ( result . output ?. statusText ) errorDetails . push ( `Status text: ${ result . output . statusText } ` ) ;
835+
836+ // Add specific suggestions for common error codes
837+ let suggestion = '' ;
838+ if ( result . output ?. status === 403 ) {
839+ suggestion = ' - This may be due to CORS restrictions or authorization issues' ;
840+ } else if ( result . output ?. status === 404 ) {
841+ suggestion = ' - The requested resource was not found' ;
842+ } else if ( result . output ?. status === 429 ) {
843+ suggestion = ' - Too many requests, you may need to implement rate limiting' ;
844+ } else if ( result . output ?. status >= 500 ) {
845+ suggestion = ' - Server error, the target server is experiencing issues' ;
846+ } else if ( result . error && result . error . includes ( 'CORS' ) ) {
847+ suggestion = ' - CORS policy prevented the request, try using a proxy or server-side request' ;
848+ } else if ( result . error && result . error . includes ( 'Failed to fetch' ) ) {
849+ suggestion = ' - Network error, check if the URL is accessible and if you have internet connectivity' ;
850+ }
851+
852+ const errorMessage = errorDetails . length > 0
853+ ? `HTTP Request failed: ${ errorDetails . join ( ' | ' ) } ${ suggestion } `
854+ : `API request to ${ tool . name || block . config . tool } failed with no error message` ;
855+
856+ // Create a detailed error object with formatted message
857+ const error = new Error ( errorMessage ) ;
858+
859+ // Add additional properties for debugging
860+ Object . assign ( error , {
861+ toolId : block . config . tool ,
862+ toolName : tool . name || 'Unknown tool' ,
863+ blockId : block . id ,
864+ blockName : block . metadata ?. name || 'Unnamed Block' ,
865+ output : result . output || { } ,
866+ status : result . output ?. status || null ,
867+ request : {
868+ url : inputs . url ,
869+ method : inputs . method || 'GET' ,
870+ } ,
871+ timestamp : new Date ( ) . toISOString ( )
872+ } ) ;
873+
874+ throw error ;
875+ }
876+
877+ return { response : result . output }
878+ } catch ( error : any ) {
879+ // Ensure we have a meaningful error message
880+ if ( ! error . message || error . message === "undefined (undefined)" ) {
881+ // Construct a detailed error message with available information
882+ let errorMessage = `API request to ${ tool . name || block . config . tool } failed` ;
883+
884+ // Add details if available
885+ if ( inputs . url ) errorMessage += `: ${ inputs . url } ` ;
886+ if ( error . status ) errorMessage += ` (Status: ${ error . status } )` ;
887+ if ( error . statusText ) errorMessage += ` - ${ error . statusText } ` ;
888+
889+ // If we still have no details, give a generic but helpful message
890+ if ( errorMessage === `API request to ${ tool . name || block . config . tool } failed` ) {
891+ errorMessage += ` - ${ block . metadata ?. name || 'Unknown error' } ` ;
892+ }
893+
894+ error . message = errorMessage ;
895+ }
896+
897+ // Add additional context to the error
898+ if ( typeof error === 'object' && error !== null ) {
899+ if ( ! error . toolId ) error . toolId = block . config . tool ;
900+ if ( ! error . blockName ) error . blockName = block . metadata ?. name || 'Unnamed Block' ;
901+
902+ // Add request details if missing
903+ if ( inputs && ! error . request ) {
904+ error . request = {
905+ url : inputs . url ,
906+ method : inputs . method || 'GET'
907+ } ;
908+ }
909+ }
910+
911+ throw error ;
912+ }
805913 }
806914}
807915
@@ -860,14 +968,63 @@ export class GenericBlockHandler implements BlockHandler {
860968 throw new Error ( `Tool not found: ${ block . config . tool } ` )
861969 }
862970
863- const result = await executeTool ( block . config . tool , {
864- ...inputs ,
865- _context : { workflowId : context . workflowId } ,
866- } )
867- if ( ! result . success ) {
868- throw new Error ( result . error || `Block execution failed with no error message` )
869- }
971+ try {
972+ const result = await executeTool ( block . config . tool , {
973+ ...inputs ,
974+ _context : { workflowId : context . workflowId } ,
975+ } )
976+
977+ if ( ! result . success ) {
978+ const errorDetails = [ ] ;
979+ if ( result . error ) errorDetails . push ( result . error ) ;
980+
981+ const errorMessage = errorDetails . length > 0
982+ ? errorDetails . join ( ' - ' )
983+ : `Block execution of ${ tool . name || block . config . tool } failed with no error message` ;
984+
985+ // Create a detailed error object with formatted message
986+ const error = new Error ( errorMessage ) ;
987+
988+ // Add additional properties for debugging
989+ Object . assign ( error , {
990+ toolId : block . config . tool ,
991+ toolName : tool . name || 'Unknown tool' ,
992+ blockId : block . id ,
993+ blockName : block . metadata ?. name || 'Unnamed Block' ,
994+ output : result . output || { } ,
995+ timestamp : new Date ( ) . toISOString ( )
996+ } ) ;
997+
998+ throw error ;
999+ }
8701000
871- return { response : result . output }
1001+ return { response : result . output }
1002+ } catch ( error : any ) {
1003+ // Ensure we have a meaningful error message
1004+ if ( ! error . message || error . message === "undefined (undefined)" ) {
1005+ // Construct a detailed error message with available information
1006+ let errorMessage = `Block execution of ${ tool . name || block . config . tool } failed` ;
1007+
1008+ // Add block name if available
1009+ if ( block . metadata ?. name ) {
1010+ errorMessage += `: ${ block . metadata . name } ` ;
1011+ }
1012+
1013+ // Add status code if available
1014+ if ( error . status ) {
1015+ errorMessage += ` (Status: ${ error . status } )` ;
1016+ }
1017+
1018+ error . message = errorMessage ;
1019+ }
1020+
1021+ // Add additional context to the error
1022+ if ( typeof error === 'object' && error !== null ) {
1023+ if ( ! error . toolId ) error . toolId = block . config . tool ;
1024+ if ( ! error . blockName ) error . blockName = block . metadata ?. name || 'Unnamed Block' ;
1025+ }
1026+
1027+ throw error ;
1028+ }
8721029 }
8731030}
0 commit comments