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 cmdBar.progressCmdBar()
|
||||
await expect(
|
||||
page.getByText('Unable to sweep with the provided selection')
|
||||
page.getByText('Unable to sweep with the current selection. Reason:')
|
||||
).toBeVisible()
|
||||
})
|
||||
})
|
||||
@ -1846,7 +1846,7 @@ sweep001 = sweep({ path = sketch002 }, sketch001)
|
||||
await page.waitForTimeout(500)
|
||||
await cmdBar.progressCmdBar()
|
||||
await expect(
|
||||
page.getByText('Unable to shell with the provided selection')
|
||||
page.getByText('Unable to shell with the current selection. Reason:')
|
||||
).toBeVisible()
|
||||
await page.waitForTimeout(1000)
|
||||
})
|
||||
|
@ -1999,7 +1999,7 @@ export class EngineCommandManager extends EventTarget {
|
||||
.catch((e) => {
|
||||
// TODO: Previously was never caught, we are not rejecting these pendingCommands but this needs to be handled at some point.
|
||||
/*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 { CommandBarContext } from 'machines/commandBarMachine'
|
||||
import { Selections } from 'lib/selections'
|
||||
import { ApiError_type } from '@kittycad/lib/dist/types/src/models'
|
||||
|
||||
export const disableDryRunWithRetry = async (numberOfRetries = 3) => {
|
||||
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 ({
|
||||
data,
|
||||
context,
|
||||
@ -83,7 +98,7 @@ export const revolveAxisValidator = async ({
|
||||
value: 360,
|
||||
}
|
||||
|
||||
const revolveAboutEdgeCommand = async () => {
|
||||
const command = async () => {
|
||||
return await engineCommandManager.sendSceneCommand({
|
||||
type: 'modeling_cmd_req',
|
||||
cmd_id: uuidv4(),
|
||||
@ -96,13 +111,13 @@ export const revolveAxisValidator = async ({
|
||||
},
|
||||
})
|
||||
}
|
||||
const attemptRevolve = await dryRunWrapper(revolveAboutEdgeCommand)
|
||||
if (attemptRevolve?.success) {
|
||||
const result = await dryRunWrapper(command)
|
||||
if (result?.success) {
|
||||
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 ({
|
||||
@ -128,7 +143,7 @@ export const loftValidator = async ({
|
||||
return 'Unable to loft, selection contains less than two solid2ds'
|
||||
}
|
||||
|
||||
const loftCommand = async () => {
|
||||
const command = async () => {
|
||||
// TODO: check what to do with these
|
||||
const DEFAULT_V_DEGREE = 2
|
||||
const DEFAULT_TOLERANCE = 2
|
||||
@ -145,13 +160,13 @@ export const loftValidator = async ({
|
||||
},
|
||||
})
|
||||
}
|
||||
const attempt = await dryRunWrapper(loftCommand)
|
||||
if (attempt?.success) {
|
||||
const result = await dryRunWrapper(command)
|
||||
if (result?.success) {
|
||||
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 ({
|
||||
@ -180,7 +195,7 @@ export const shellValidator = async ({
|
||||
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
|
||||
const DEFAULT_THICKNESS: Models['LengthUnit_type'] = 1e-9
|
||||
const DEFAULT_HOLLOW = false
|
||||
@ -200,12 +215,13 @@ export const shellValidator = async ({
|
||||
})
|
||||
}
|
||||
|
||||
const attemptShell = await dryRunWrapper(shellCommand)
|
||||
if (attemptShell?.success) {
|
||||
const result = await dryRunWrapper(command)
|
||||
if (result?.success) {
|
||||
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 ({
|
||||
@ -241,7 +257,7 @@ export const sweepValidator = async ({
|
||||
}
|
||||
const target = targetArtifact.pathId
|
||||
|
||||
const sweepCommand = async () => {
|
||||
const command = async () => {
|
||||
// TODO: second look on defaults here
|
||||
const DEFAULT_TOLERANCE: Models['LengthUnit_type'] = 1e-7
|
||||
const DEFAULT_SECTIONAL = false
|
||||
@ -261,10 +277,11 @@ export const sweepValidator = async ({
|
||||
})
|
||||
}
|
||||
|
||||
const attemptSweep = await dryRunWrapper(sweepCommand)
|
||||
if (attemptSweep?.success) {
|
||||
const result = await dryRunWrapper(command)
|
||||
if (result?.success) {
|
||||
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