Skip to content

Commit

Permalink
http-request-actions: Add proper error handling to callback generation
Browse files Browse the repository at this point in the history
  • Loading branch information
rafaellehmkuhl authored and ArturoManzoli committed Nov 21, 2024
1 parent d0d57b0 commit 591705c
Showing 1 changed file with 108 additions and 80 deletions.
188 changes: 108 additions & 80 deletions src/libs/actions/http-request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,95 +112,123 @@ export type HttpRequestActionCallback = () => void

export const getHttpRequestActionCallback = (id: string): HttpRequestActionCallback => {
return () => {
const action = getHttpRequestActionConfig(id)
if (!action) {
throw new Error(`Action with id ${id} not found.`)
}
try {
const action = getHttpRequestActionConfig(id)
if (!action) {
throw new Error(`Action with id ${id} not found.`)
}

let parsedBody = action.body
const parsedUrlParams = { ...action.urlParams }

const cockpitInputsInBody = action.body.match(/{{\s*([^{}\s]+)\s*}}/g)
if (cockpitInputsInBody) {
for (const input of cockpitInputsInBody) {
const parsedInput = input.replace('{{', '').replace('}}', '').trim()
const inputData = getCockpitActionVariableData(parsedInput)
const variableInfo = getCockpitActionVariableInfo(parsedInput)

if (inputData !== undefined) {
let valueToReplace: string

// Determine type either from variable info or by parsing the value
const type =
variableInfo?.type ||
(() => {
const strValue = inputData.toString().toLowerCase()
// Check if it's a boolean
if (strValue === 'true' || strValue === 'false') {
return 'boolean'
}
// Check if it's a number
if (!isNaN(Number(strValue)) && strValue !== '') {
return 'number'
let parsedBody = action.body
const parsedUrlParams = { ...action.urlParams }

// Parse body variables
try {
const cockpitInputsInBody = action.body.match(/{{\s*([^{}\s]+)\s*}}/g)
if (cockpitInputsInBody) {
for (const input of cockpitInputsInBody) {
try {
const parsedInput = input.replace('{{', '').replace('}}', '').trim()
const inputData = getCockpitActionVariableData(parsedInput)
const variableInfo = getCockpitActionVariableInfo(parsedInput)

if (inputData !== undefined) {
let valueToReplace: string

try {
// Determine type either from variable info or by parsing the value
const type =
variableInfo?.type ||
(() => {
const strValue = inputData.toString().toLowerCase()
// Check if it's a boolean
if (strValue === 'true' || strValue === 'false') {
return 'boolean'
}
// Check if it's a number
if (!isNaN(Number(strValue)) && strValue !== '') {
return 'number'
}
return 'string'
})()

// Cast the value based on the determined type
switch (type) {
case 'number':
case 'boolean':
valueToReplace = inputData.toString()
// Remove quotes if they exist around the placeholder
parsedBody = parsedBody.replace(`"${input}"`, valueToReplace)
// If no quotes found, replace the placeholder directly
if (parsedBody.includes(input)) {
parsedBody = parsedBody.replace(input, valueToReplace)
}
break
case 'string':
valueToReplace = `"${inputData.toString()}"`
// Replace the placeholder, maintaining the quotes if they exist
parsedBody = parsedBody.replace(`"${input}"`, valueToReplace)
// If no quotes found, replace and add them
if (parsedBody.includes(input)) {
parsedBody = parsedBody.replace(input, valueToReplace)
}
break
}
} catch (error) {
console.warn(`Error parsing value for ${input}, using as string:`, error)
// Fallback to string if parsing fails
valueToReplace = `"${inputData.toString()}"`
parsedBody = parsedBody.replace(input, valueToReplace)
}
}
return 'string'
})()

// Cast the value based on the determined type
switch (type) {
case 'number':
valueToReplace = inputData.toString()
// Remove quotes if they exist around the placeholder
parsedBody = parsedBody.replace(`"${input}"`, valueToReplace)
// If no quotes found, replace the placeholder directly
if (parsedBody.includes(input)) {
parsedBody = parsedBody.replace(input, valueToReplace)
}
break
case 'boolean':
valueToReplace = inputData.toString()
// Remove quotes if they exist around the placeholder
parsedBody = parsedBody.replace(`"${input}"`, valueToReplace)
// If no quotes found, replace the placeholder directly
if (parsedBody.includes(input)) {
parsedBody = parsedBody.replace(input, valueToReplace)
}
break
case 'string':
valueToReplace = `"${inputData.toString()}"`
// Replace the placeholder, maintaining the quotes if they exist
parsedBody = parsedBody.replace(`"${input}"`, valueToReplace)
// If no quotes found, replace and add them
if (parsedBody.includes(input)) {
parsedBody = parsedBody.replace(input, valueToReplace)
}
break
} catch (error) {
console.warn(`Error processing body variable ${input}:`, error)
}
}
}
} catch (error) {
console.error('Error parsing body variables:', error)
}
}

const cockpitInputsInUrlParams = Object.entries(action.urlParams).filter(
([, value]) => typeof value === 'string' && value.startsWith('{{') && value.endsWith('}}')
)
if (cockpitInputsInUrlParams) {
for (const [key, value] of cockpitInputsInUrlParams) {
const parsedInput = value.replace('{{', '').replace('}}', '').trim()
const inputData = getCockpitActionVariableData(parsedInput)
if (inputData) {
parsedUrlParams[key] = inputData.toString()
// Parse URL parameters
try {
const cockpitInputsInUrlParams = Object.entries(action.urlParams).filter(
([, value]) => typeof value === 'string' && value.startsWith('{{') && value.endsWith('}}')
)
if (cockpitInputsInUrlParams) {
for (const [key, value] of cockpitInputsInUrlParams) {
try {
const parsedInput = value.replace('{{', '').replace('}}', '').trim()
const inputData = getCockpitActionVariableData(parsedInput)
if (inputData) {
parsedUrlParams[key] = inputData.toString()
}
} catch (error) {
console.warn(`Error processing URL parameter ${key}:`, error)
}
}
}
} catch (error) {
console.error('Error parsing URL parameters:', error)
}
}

const url = new URL(action.url)
url.search = new URLSearchParams(parsedUrlParams).toString()

fetch(url, {
method: action.method,
headers: action.headers,
body: action.method === HttpRequestMethod.GET ? undefined : parsedBody,
})
// Make the request
try {
const url = new URL(action.url)
url.search = new URLSearchParams(parsedUrlParams).toString()

fetch(url, {
method: action.method,
headers: action.headers,
body: action.method === HttpRequestMethod.GET ? undefined : parsedBody,
}).catch((error) => {
console.error('Fetch request failed:', error)
})
} catch (error) {
console.error('Error making HTTP request:', error)
}
} catch (error) {
console.error('Error executing HTTP request action:', error)
}
}
}

Expand Down

0 comments on commit 591705c

Please sign in to comment.