Compare commits
2 Commits
mirror-2d-
...
jtran/json
Author | SHA1 | Date | |
---|---|---|---|
4a5ef17c92 | |||
83220a7255 |
@ -3,6 +3,7 @@ import { useEffect, useState } from 'react'
|
|||||||
import type { CommandLog } from '@src/lang/std/commandLog'
|
import type { CommandLog } from '@src/lang/std/commandLog'
|
||||||
import { engineCommandManager } from '@src/lib/singletons'
|
import { engineCommandManager } from '@src/lib/singletons'
|
||||||
import { reportRejection } from '@src/lib/trap'
|
import { reportRejection } from '@src/lib/trap'
|
||||||
|
import { parseJson } from '@src/lib/utils'
|
||||||
|
|
||||||
export function useEngineCommands(): [CommandLog[], () => void] {
|
export function useEngineCommands(): [CommandLog[], () => void] {
|
||||||
const [engineCommands, setEngineCommands] = useState<CommandLog[]>(
|
const [engineCommands, setEngineCommands] = useState<CommandLog[]>(
|
||||||
@ -84,7 +85,7 @@ export const EngineCommands = () => {
|
|||||||
data-testid="custom-cmd-send-button"
|
data-testid="custom-cmd-send-button"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
engineCommandManager
|
engineCommandManager
|
||||||
.sendSceneCommand(JSON.parse(customCmd))
|
.sendSceneCommand(parseJson(customCmd))
|
||||||
.catch(reportRejection)
|
.catch(reportRejection)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
@ -4,6 +4,7 @@ import path from 'node:path'
|
|||||||
import { assertParse } from '@src/lang/wasm'
|
import { assertParse } from '@src/lang/wasm'
|
||||||
import { initPromise } from '@src/lang/wasmUtils'
|
import { initPromise } from '@src/lang/wasmUtils'
|
||||||
import { enginelessExecutor } from '@src/lib/testHelpers'
|
import { enginelessExecutor } from '@src/lib/testHelpers'
|
||||||
|
import { parseJson } from '@src/lib/utils'
|
||||||
|
|
||||||
// The purpose of these tests is to act as a first line of defense
|
// The purpose of these tests is to act as a first line of defense
|
||||||
// if something gets real screwy with our KCL ecosystem.
|
// if something gets real screwy with our KCL ecosystem.
|
||||||
@ -27,7 +28,7 @@ const manifestJsonStr = await fs.readFile(
|
|||||||
path.resolve(DIR_KCL_SAMPLES, 'manifest.json'),
|
path.resolve(DIR_KCL_SAMPLES, 'manifest.json'),
|
||||||
'utf-8'
|
'utf-8'
|
||||||
)
|
)
|
||||||
const manifest = JSON.parse(manifestJsonStr)
|
const manifest: KclSampleFile[] = parseJson(manifestJsonStr)
|
||||||
|
|
||||||
process.chdir(DIR_KCL_SAMPLES)
|
process.chdir(DIR_KCL_SAMPLES)
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ import {
|
|||||||
getThemeColorForEngine,
|
getThemeColorForEngine,
|
||||||
} from '@src/lib/theme'
|
} from '@src/lib/theme'
|
||||||
import { reportRejection } from '@src/lib/trap'
|
import { reportRejection } from '@src/lib/trap'
|
||||||
import { binaryToUuid, uuidv4 } from '@src/lib/utils'
|
import { binaryToUuid, parseJson, uuidv4 } from '@src/lib/utils'
|
||||||
|
|
||||||
const pingIntervalMs = 1_000
|
const pingIntervalMs = 1_000
|
||||||
|
|
||||||
@ -390,7 +390,7 @@ class EngineConnection extends EventTarget {
|
|||||||
this.websocket.addEventListener('open', this.onWebSocketOpen)
|
this.websocket.addEventListener('open', this.onWebSocketOpen)
|
||||||
|
|
||||||
this.websocket?.addEventListener('message', ((event: MessageEvent) => {
|
this.websocket?.addEventListener('message', ((event: MessageEvent) => {
|
||||||
const message: Models['WebSocketResponse_type'] = JSON.parse(event.data)
|
const message: Models['WebSocketResponse_type'] = parseJson(event.data)
|
||||||
const pending =
|
const pending =
|
||||||
this.engineCommandManager.pendingCommands[message.request_id || '']
|
this.engineCommandManager.pendingCommands[message.request_id || '']
|
||||||
if (!('resp' in message)) return
|
if (!('resp' in message)) return
|
||||||
@ -862,7 +862,7 @@ class EngineConnection extends EventTarget {
|
|||||||
)
|
)
|
||||||
|
|
||||||
this.onDataChannelMessage = (event) => {
|
this.onDataChannelMessage = (event) => {
|
||||||
const result: UnreliableResponses = JSON.parse(event.data)
|
const result: UnreliableResponses = parseJson(event.data)
|
||||||
Object.values(
|
Object.values(
|
||||||
this.engineCommandManager.unreliableSubscriptions[result.type] ||
|
this.engineCommandManager.unreliableSubscriptions[result.type] ||
|
||||||
{}
|
{}
|
||||||
@ -976,7 +976,7 @@ class EngineConnection extends EventTarget {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const message: Models['WebSocketResponse_type'] = JSON.parse(
|
const message: Models['WebSocketResponse_type'] = parseJson(
|
||||||
event.data
|
event.data
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -1564,7 +1564,7 @@ export class EngineCommandManager extends EventTarget {
|
|||||||
unreliableDataChannel.addEventListener(
|
unreliableDataChannel.addEventListener(
|
||||||
'message',
|
'message',
|
||||||
(event: MessageEvent) => {
|
(event: MessageEvent) => {
|
||||||
const result: UnreliableResponses = JSON.parse(event.data)
|
const result: UnreliableResponses = parseJson(event.data)
|
||||||
Object.values(
|
Object.values(
|
||||||
this.unreliableSubscriptions[result.type] || {}
|
this.unreliableSubscriptions[result.type] || {}
|
||||||
).forEach(
|
).forEach(
|
||||||
@ -1608,7 +1608,7 @@ export class EngineCommandManager extends EventTarget {
|
|||||||
message.request_id = binaryToUuid(message.request_id)
|
message.request_id = binaryToUuid(message.request_id)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
message = JSON.parse(event.data)
|
message = parseJson(event.data)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message === null) {
|
if (message === null) {
|
||||||
|
@ -40,7 +40,7 @@ import type { CoreDumpManager } from '@src/lib/coredump'
|
|||||||
import openWindow from '@src/lib/openWindow'
|
import openWindow from '@src/lib/openWindow'
|
||||||
import { Reason, err } from '@src/lib/trap'
|
import { Reason, err } from '@src/lib/trap'
|
||||||
import type { DeepPartial } from '@src/lib/types'
|
import type { DeepPartial } from '@src/lib/types'
|
||||||
import { isArray } from '@src/lib/utils'
|
import { isArray, parseJson } from '@src/lib/utils'
|
||||||
import {
|
import {
|
||||||
base64_decode,
|
base64_decode,
|
||||||
change_kcl_settings,
|
change_kcl_settings,
|
||||||
@ -217,9 +217,7 @@ export const parse = (code: string | Error): ParseResult | Error => {
|
|||||||
let errs = splitErrors(parsed[1])
|
let errs = splitErrors(parsed[1])
|
||||||
return new ParseResult(parsed[0], errs.errors, errs.warnings)
|
return new ParseResult(parsed[0], errs.errors, errs.warnings)
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
// throw e
|
const parsed: RustKclError = parseJson(e.toString())
|
||||||
console.error(e.toString())
|
|
||||||
const parsed: RustKclError = JSON.parse(e.toString())
|
|
||||||
return new KCLError(
|
return new KCLError(
|
||||||
parsed.kind,
|
parsed.kind,
|
||||||
parsed.msg,
|
parsed.msg,
|
||||||
@ -381,7 +379,7 @@ export function sketchFromKclValue(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const errFromErrWithOutputs = (e: any): KCLError => {
|
export const errFromErrWithOutputs = (e: any): KCLError => {
|
||||||
const parsed: KclErrorWithOutputs = JSON.parse(e.toString())
|
const parsed: KclErrorWithOutputs = parseJson(e.toString())
|
||||||
return new KCLError(
|
return new KCLError(
|
||||||
parsed.error.kind,
|
parsed.error.kind,
|
||||||
parsed.error.msg,
|
parsed.error.msg,
|
||||||
|
@ -3,7 +3,7 @@ import type { ApiError_type } from '@kittycad/lib/dist/types/src/models'
|
|||||||
|
|
||||||
import type { Selections } from '@src/lib/selections'
|
import type { Selections } from '@src/lib/selections'
|
||||||
import { engineCommandManager, kclManager } from '@src/lib/singletons'
|
import { engineCommandManager, kclManager } from '@src/lib/singletons'
|
||||||
import { uuidv4 } from '@src/lib/utils'
|
import { parseJson, uuidv4 } from '@src/lib/utils'
|
||||||
import type { CommandBarContext } from '@src/machines/commandBarMachine'
|
import type { CommandBarContext } from '@src/machines/commandBarMachine'
|
||||||
|
|
||||||
export const disableDryRunWithRetry = async (numberOfRetries = 3) => {
|
export const disableDryRunWithRetry = async (numberOfRetries = 3) => {
|
||||||
@ -54,7 +54,7 @@ export function parseEngineErrorMessage(engineError: string) {
|
|||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
const errors = JSON.parse(parts[1]) as ApiError_type[]
|
const errors = parseJson<ApiError_type[]>(parts[1])
|
||||||
if (!errors[0]) {
|
if (!errors[0]) {
|
||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ import type { DeepPartial } from '@src/lib/types'
|
|||||||
import type { ModuleType } from '@src/lib/wasm_lib_wrapper'
|
import type { ModuleType } from '@src/lib/wasm_lib_wrapper'
|
||||||
import { getModule } from '@src/lib/wasm_lib_wrapper'
|
import { getModule } from '@src/lib/wasm_lib_wrapper'
|
||||||
import type { Models } from '@kittycad/lib/dist/types/src'
|
import type { Models } from '@kittycad/lib/dist/types/src'
|
||||||
|
import { parseJson } from '@src/lib/utils'
|
||||||
|
|
||||||
export default class RustContext {
|
export default class RustContext {
|
||||||
private wasmInitFailed: boolean = true
|
private wasmInitFailed: boolean = true
|
||||||
@ -140,7 +141,7 @@ export default class RustContext {
|
|||||||
JSON.stringify(settings)
|
JSON.stringify(settings)
|
||||||
)
|
)
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
const parsed: RustKclError = JSON.parse(e.toString())
|
const parsed: RustKclError = parseJson(e.toString())
|
||||||
toast.error(parsed.msg, { id: toastId })
|
toast.error(parsed.msg, { id: toastId })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -60,6 +60,26 @@ export function isNonNullable<T>(val: T): val is NonNullable<T> {
|
|||||||
return val !== null && val !== undefined
|
return val !== null && val !== undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Same as JSON.parse() but if it fails, includes the string that was attempted
|
||||||
|
* to be parsed in the error message. This is useful since a lot of times this
|
||||||
|
* is called on a string that isn't actually JSON, like another error message.
|
||||||
|
*
|
||||||
|
* You can also use the type parameter to assert the expected type of the parsed
|
||||||
|
* object.
|
||||||
|
*/
|
||||||
|
export function parseJson<T>(
|
||||||
|
text: string,
|
||||||
|
reviver?: (this: any, key: string, value: any) => any
|
||||||
|
): T {
|
||||||
|
try {
|
||||||
|
return JSON.parse(text, reviver)
|
||||||
|
} catch (e) {
|
||||||
|
// eslint-disable-next-line suggest-no-throw/suggest-no-throw
|
||||||
|
throw new Error(`Failed to parse JSON: ${text}`, { cause: e })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function isOverlap(a: SourceRange, b: SourceRange) {
|
export function isOverlap(a: SourceRange, b: SourceRange) {
|
||||||
const [startingRange, secondRange] = a[0] < b[0] ? [a, b] : [b, a]
|
const [startingRange, secondRange] = a[0] < b[0] ? [a, b] : [b, a]
|
||||||
const [lastOfFirst, firstOfSecond] = [startingRange[1], secondRange[0]]
|
const [lastOfFirst, firstOfSecond] = [startingRange[1], secondRange[0]]
|
||||||
|
Reference in New Issue
Block a user