Automate API Circuit breaker (#3914)
* fix(automate): invokeSafeJsonRequest * fix(automate): correct fallback values
This commit is contained in:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user