Add engine message to dry run validation error toasts (#5175)
* Add engine message to dry run validation error toasts Fixes #5174 * A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores) * Trigger CI * A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores) * A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores) * Add unit tests * A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores) * Reset snapshots * A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores) * Revert snapshot changes * Fix lint * Fix test --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
@ -1078,7 +1078,7 @@ sketch002 = startSketchOn('XZ')
|
|||||||
await page.waitForTimeout(500)
|
await page.waitForTimeout(500)
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await expect(
|
await expect(
|
||||||
page.getByText('Unable to sweep with the provided selection')
|
page.getByText('Unable to sweep with the current selection. Reason:')
|
||||||
).toBeVisible()
|
).toBeVisible()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -1846,7 +1846,7 @@ sweep001 = sweep({ path = sketch002 }, sketch001)
|
|||||||
await page.waitForTimeout(500)
|
await page.waitForTimeout(500)
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await expect(
|
await expect(
|
||||||
page.getByText('Unable to shell with the provided selection')
|
page.getByText('Unable to shell with the current selection. Reason:')
|
||||||
).toBeVisible()
|
).toBeVisible()
|
||||||
await page.waitForTimeout(1000)
|
await page.waitForTimeout(1000)
|
||||||
})
|
})
|
||||||
|
@ -1999,7 +1999,7 @@ export class EngineCommandManager extends EventTarget {
|
|||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
// TODO: Previously was never caught, we are not rejecting these pendingCommands but this needs to be handled at some point.
|
// TODO: Previously was never caught, we are not rejecting these pendingCommands but this needs to be handled at some point.
|
||||||
/*noop*/
|
/*noop*/
|
||||||
return null
|
return e
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
19
src/lib/commandBarConfigs/validators.test.ts
Normal file
19
src/lib/commandBarConfigs/validators.test.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { parseEngineErrorMessage } from './validators'
|
||||||
|
|
||||||
|
describe('parseEngineErrorMessage', () => {
|
||||||
|
it('takes an engine error string and parses its json message', () => {
|
||||||
|
const engineError =
|
||||||
|
'engine error: [{"error_code":"internal_engine","message":"Trajectory curve must be G1 continuous (with continuous tangents)"}]'
|
||||||
|
const message = parseEngineErrorMessage(engineError)
|
||||||
|
expect(message).toEqual(
|
||||||
|
'Trajectory curve must be G1 continuous (with continuous tangents)'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('retuns undefined on strings with different formats', () => {
|
||||||
|
const s1 = 'engine error: []'
|
||||||
|
const s2 = 'blabla'
|
||||||
|
expect(parseEngineErrorMessage(s1)).toBeUndefined()
|
||||||
|
expect(parseEngineErrorMessage(s2)).toBeUndefined()
|
||||||
|
})
|
||||||
|
})
|
@ -3,6 +3,7 @@ import { engineCommandManager } from 'lib/singletons'
|
|||||||
import { uuidv4 } from 'lib/utils'
|
import { uuidv4 } from 'lib/utils'
|
||||||
import { CommandBarContext } from 'machines/commandBarMachine'
|
import { CommandBarContext } from 'machines/commandBarMachine'
|
||||||
import { Selections } from 'lib/selections'
|
import { Selections } from 'lib/selections'
|
||||||
|
import { ApiError_type } from '@kittycad/lib/dist/types/src/models'
|
||||||
|
|
||||||
export const disableDryRunWithRetry = async (numberOfRetries = 3) => {
|
export const disableDryRunWithRetry = async (numberOfRetries = 3) => {
|
||||||
for (let tries = 0; tries < numberOfRetries; tries++) {
|
for (let tries = 0; tries < numberOfRetries; tries++) {
|
||||||
@ -46,6 +47,20 @@ function isSelections(selections: unknown): selections is Selections {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function parseEngineErrorMessage(engineError: string) {
|
||||||
|
const parts = engineError.split('engine error: ')
|
||||||
|
if (parts.length < 2) {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
const errors = JSON.parse(parts[1]) as ApiError_type[]
|
||||||
|
if (!errors[0]) {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors[0].message
|
||||||
|
}
|
||||||
|
|
||||||
export const revolveAxisValidator = async ({
|
export const revolveAxisValidator = async ({
|
||||||
data,
|
data,
|
||||||
context,
|
context,
|
||||||
@ -83,7 +98,7 @@ export const revolveAxisValidator = async ({
|
|||||||
value: 360,
|
value: 360,
|
||||||
}
|
}
|
||||||
|
|
||||||
const revolveAboutEdgeCommand = async () => {
|
const command = async () => {
|
||||||
return await engineCommandManager.sendSceneCommand({
|
return await engineCommandManager.sendSceneCommand({
|
||||||
type: 'modeling_cmd_req',
|
type: 'modeling_cmd_req',
|
||||||
cmd_id: uuidv4(),
|
cmd_id: uuidv4(),
|
||||||
@ -96,13 +111,13 @@ export const revolveAxisValidator = async ({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
const attemptRevolve = await dryRunWrapper(revolveAboutEdgeCommand)
|
const result = await dryRunWrapper(command)
|
||||||
if (attemptRevolve?.success) {
|
if (result?.success) {
|
||||||
return true
|
return true
|
||||||
} else {
|
|
||||||
// return error message for the toast
|
|
||||||
return 'Unable to revolve with selected edge'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const reason = parseEngineErrorMessage(result) || 'unknown'
|
||||||
|
return `Unable to revolve with the current selection. Reason: ${reason}`
|
||||||
}
|
}
|
||||||
|
|
||||||
export const loftValidator = async ({
|
export const loftValidator = async ({
|
||||||
@ -128,7 +143,7 @@ export const loftValidator = async ({
|
|||||||
return 'Unable to loft, selection contains less than two solid2ds'
|
return 'Unable to loft, selection contains less than two solid2ds'
|
||||||
}
|
}
|
||||||
|
|
||||||
const loftCommand = async () => {
|
const command = async () => {
|
||||||
// TODO: check what to do with these
|
// TODO: check what to do with these
|
||||||
const DEFAULT_V_DEGREE = 2
|
const DEFAULT_V_DEGREE = 2
|
||||||
const DEFAULT_TOLERANCE = 2
|
const DEFAULT_TOLERANCE = 2
|
||||||
@ -145,13 +160,13 @@ export const loftValidator = async ({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
const attempt = await dryRunWrapper(loftCommand)
|
const result = await dryRunWrapper(command)
|
||||||
if (attempt?.success) {
|
if (result?.success) {
|
||||||
return true
|
return true
|
||||||
} else {
|
|
||||||
// return error message for the toast
|
|
||||||
return 'Unable to loft with selected sketches'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const reason = parseEngineErrorMessage(result) || 'unknown'
|
||||||
|
return `Unable to loft with the current selection. Reason: ${reason}`
|
||||||
}
|
}
|
||||||
|
|
||||||
export const shellValidator = async ({
|
export const shellValidator = async ({
|
||||||
@ -180,7 +195,7 @@ export const shellValidator = async ({
|
|||||||
return "Unable to shell, couldn't find the solid"
|
return "Unable to shell, couldn't find the solid"
|
||||||
}
|
}
|
||||||
|
|
||||||
const shellCommand = async () => {
|
const command = async () => {
|
||||||
// TODO: figure out something better than an arbitrarily small value
|
// TODO: figure out something better than an arbitrarily small value
|
||||||
const DEFAULT_THICKNESS: Models['LengthUnit_type'] = 1e-9
|
const DEFAULT_THICKNESS: Models['LengthUnit_type'] = 1e-9
|
||||||
const DEFAULT_HOLLOW = false
|
const DEFAULT_HOLLOW = false
|
||||||
@ -200,12 +215,13 @@ export const shellValidator = async ({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const attemptShell = await dryRunWrapper(shellCommand)
|
const result = await dryRunWrapper(command)
|
||||||
if (attemptShell?.success) {
|
if (result?.success) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
return 'Unable to shell with the provided selection'
|
const reason = parseEngineErrorMessage(result) || 'unknown'
|
||||||
|
return `Unable to shell with the current selection. Reason: ${reason}`
|
||||||
}
|
}
|
||||||
|
|
||||||
export const sweepValidator = async ({
|
export const sweepValidator = async ({
|
||||||
@ -241,7 +257,7 @@ export const sweepValidator = async ({
|
|||||||
}
|
}
|
||||||
const target = targetArtifact.pathId
|
const target = targetArtifact.pathId
|
||||||
|
|
||||||
const sweepCommand = async () => {
|
const command = async () => {
|
||||||
// TODO: second look on defaults here
|
// TODO: second look on defaults here
|
||||||
const DEFAULT_TOLERANCE: Models['LengthUnit_type'] = 1e-7
|
const DEFAULT_TOLERANCE: Models['LengthUnit_type'] = 1e-7
|
||||||
const DEFAULT_SECTIONAL = false
|
const DEFAULT_SECTIONAL = false
|
||||||
@ -261,10 +277,11 @@ export const sweepValidator = async ({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const attemptSweep = await dryRunWrapper(sweepCommand)
|
const result = await dryRunWrapper(command)
|
||||||
if (attemptSweep?.success) {
|
if (result?.success) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
return 'Unable to sweep with the provided selection'
|
const reason = parseEngineErrorMessage(result) || 'unknown'
|
||||||
|
return `Unable to sweep with the current selection. Reason: ${reason}`
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user