Automate API Circuit breaker (#3914)

* fix(automate): invokeSafeJsonRequest

* fix(automate): correct fallback values
This commit is contained in:
Chuck Driesler
2025-01-30 15:26:12 +00:00
committed by GitHub
parent a3d1e6adec
commit 4cbeeef0d0
4 changed files with 67 additions and 19 deletions
@@ -74,6 +74,23 @@ const getApiUrl = (
return url.toString()
}
const invokeSafeJsonRequest = async <
Response extends Record<string, unknown> = Record<string, unknown>
>(
...args: Parameters<typeof invokeRequest>
): Promise<Response | null> => {
const [{ url, method }] = args
try {
return await invokeJsonRequest<Response>(...args)
} catch (e) {
automateLogger.error(
{ url, method, err: e },
'Automate API request error suppressed.'
)
return null
}
}
const invokeJsonRequest = async <R = Record<string, unknown>>(
...args: Parameters<typeof invokeRequest>
) => {
@@ -381,13 +398,11 @@ export const getFunction = async (params: {
query
})
const result = await invokeJsonRequest<GetFunctionResponse>({
return await invokeSafeJsonRequest<GetFunctionResponse>({
url,
method: 'get',
token
})
return result
}
export type GetFunctionReleaseResponse = FunctionReleaseSchemaType
@@ -429,15 +444,17 @@ export const getFunctionRelease = async (params: {
const { functionId, functionReleaseId } = params
const url = getApiUrl(`/api/v1/functions/${functionId}/versions/${functionReleaseId}`)
const result = await invokeJsonRequest<GetFunctionReleaseResponse>({
const result = await invokeSafeJsonRequest<GetFunctionReleaseResponse>({
url,
method: 'get'
})
return {
...result,
functionId
}
return result
? {
...result,
functionId
}
: null
}
export type GetFunctionsResponse = {
@@ -461,12 +478,11 @@ export const getPublicFunctions = async (params: {
featuredFunctionsOnly: true
}
})
const result = await invokeJsonRequest<GetFunctionsResponse>({
return await invokeSafeJsonRequest<GetFunctionsResponse>({
url,
method: 'get'
})
return result
}
type GetUserFunctionsResponse = {
@@ -483,11 +499,11 @@ export const getUserFunctions = async (params: {
body: {
speckleServerAuthenticationPayload: AuthCodePayloadWithOrigin
}
}): Promise<GetUserFunctionsResponse> => {
}) => {
const { userId, query, body } = params
const url = getApiUrl(`/api/v2/users/${userId}/functions`, { query })
return await invokeJsonRequest({
return await invokeSafeJsonRequest<GetUserFunctionsResponse>({
url,
method: 'POST',
body,
@@ -509,11 +525,11 @@ export const getWorkspaceFunctions = async (params: {
body: {
speckleServerAuthenticationPayload: AuthCodePayloadWithOrigin
}
}): Promise<GetWorkspaceFunctionsResponse> => {
}) => {
const { workspaceId, query, body } = params
const url = getApiUrl(`/api/v2/workspaces/${workspaceId}/functions`, { query })
return await invokeJsonRequest({
return await invokeSafeJsonRequest<GetWorkspaceFunctionsResponse>({
url,
method: 'POST',
body,
@@ -473,6 +473,14 @@ export = (FF_AUTOMATE_MODULE_ENABLED
: {}
})
if (!fn) {
return {
cursor: null,
totalCount: 0,
items: []
}
}
return {
cursor: fn.versionCursor,
totalCount: fn.versionCount,
@@ -749,6 +757,14 @@ export = (FF_AUTOMATE_MODULE_ENABLED
}
})
if (!res) {
return {
cursor: null,
totalCount: 0,
items: []
}
}
const items = res.items.map(convertFunctionToGraphQLReturn)
return {
@@ -798,6 +814,14 @@ export = (FF_AUTOMATE_MODULE_ENABLED
}
})
if (!res) {
return {
cursor: null,
totalCount: 0,
items: []
}
}
const items = res.functions.map(convertFunctionToGraphQLReturn)
return {
@@ -183,16 +183,16 @@ export const createTestAutomationFactory =
)
// Get latest release for specified function
const { functionVersions: functionReleases } = await getFunction({ functionId })
const fn = await getFunction({ functionId })
if (!functionReleases || functionReleases.length === 0) {
if (!fn || !fn.functionVersions || fn.functionVersions.length === 0) {
// TODO: This should probably be okay for test automations
throw new AutomationCreationError(
'The specified function does not have any releases'
)
}
const latestFunctionRelease = functionReleases[0]
const latestFunctionRelease = fn.functionVersions[0]
// Create and store the automation record
const automationId = cryptoRandomString({ length: 10 })
@@ -380,7 +380,7 @@ const validateNewRevisionFunctions =
),
(r) =>
updateId({
functionReleaseId: r.functionVersionId,
functionReleaseId: r?.functionVersionId ?? '',
functionId: r.functionId
})
)
@@ -1171,6 +1171,14 @@ export = FF_WORKSPACES_MODULE_ENABLED
}
})
if (!res) {
return {
cursor: null,
totalCount: 0,
items: []
}
}
const items = res.functions.map(convertFunctionToGraphQLReturn)
return {