mirror of
https://github.com/misode/misode.github.io.git
synced 2026-04-27 00:38:46 +00:00
Wrap all JSON.parse calls with try-catch
This commit is contained in:
@@ -2,6 +2,7 @@ import type { DocAndNode } from '@spyglassmc/core'
|
||||
import { useState } from 'preact/hooks'
|
||||
import { Analytics } from '../../Analytics.js'
|
||||
import { useLocale, useProject } from '../../contexts/index.js'
|
||||
import { safeJsonParse } from '../../Utils.js'
|
||||
import { Btn } from '../Btn.js'
|
||||
import { TextInput } from '../forms/index.js'
|
||||
import { Modal } from '../Modal.js'
|
||||
@@ -29,8 +30,11 @@ export function FileCreation({ docAndNode, id, method, onClose }: Props) {
|
||||
return
|
||||
}
|
||||
Analytics.saveProjectFile(id, projects.length, project.files.length, method as any)
|
||||
const data = JSON.parse(docAndNode.doc.getText())
|
||||
updateFile(id, undefined, { type: id, id: fileId, data })
|
||||
const text = docAndNode.doc.getText()
|
||||
const data = safeJsonParse(text)
|
||||
if (data !== undefined) {
|
||||
updateFile(id, undefined, { type: id, id: fileId, data })
|
||||
}
|
||||
onClose()
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import type { DocAndNode } from '@spyglassmc/core'
|
||||
import { useDocAndNode } from '../../contexts/Spyglass.jsx'
|
||||
import { useVersion } from '../../contexts/Version.jsx'
|
||||
import { checkVersion } from '../../services/index.js'
|
||||
import { safeJsonParse } from '../../Utils.js'
|
||||
import { BiomeSourcePreview, BlockStatePreview, DecoratorPreview, DensityFunctionPreview, LootTablePreview, ModelPreview, NoisePreview, NoiseSettingsPreview, RecipePreview, StructureSetPreview } from '../previews/index.js'
|
||||
|
||||
export const HasPreview = ['loot_table', 'recipe', 'dimension', 'worldgen/density_function', 'worldgen/noise', 'worldgen/noise_settings', 'worldgen/configured_feature', 'worldgen/placed_feature', 'worldgen/structure_set', 'block_definition', 'docAndNode']
|
||||
@@ -27,7 +28,7 @@ export function PreviewPanel({ docAndNode: original, id, shown }: PreviewPanelPr
|
||||
return <RecipePreview {...{ docAndNode, shown }} />
|
||||
}
|
||||
|
||||
if (id === 'dimension' && JSON.parse(docAndNode.doc.getText()).generator?.type?.endsWith('noise')) {
|
||||
if (id === 'dimension' && safeJsonParse(docAndNode.doc.getText())?.generator?.type?.endsWith('noise')) {
|
||||
return <BiomeSourcePreview {...{ docAndNode, shown }} />
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import { AsyncCancel, useActiveTimeout, useAsync, useSearchParam } from '../../h
|
||||
import type { VersionId } from '../../services/index.js'
|
||||
import { checkVersion, fetchPreset, fetchRegistries, getSnippet, shareSnippet } from '../../services/index.js'
|
||||
import { Store } from '../../Store.js'
|
||||
import { cleanUrl, genPath } from '../../Utils.js'
|
||||
import { cleanUrl, genPath, safeJsonParse } from '../../Utils.js'
|
||||
import { Ad, Btn, BtnMenu, ErrorPanel, FileCreation, FileRenaming, Footer, HasPreview, Octicon, PreviewPanel, ProjectCreation, ProjectDeletion, ProjectPanel, SearchList, SourcePanel, TextInput, Tree, VersionSwitcher } from '../index.js'
|
||||
|
||||
export const SHARE_KEY = 'share'
|
||||
@@ -102,8 +102,10 @@ export function SchemaGenerator({ gen, allowedVersions }: Props) {
|
||||
setSharedSnippetId(undefined, true)
|
||||
}
|
||||
if (file) {
|
||||
const data = JSON.parse(doc.getText())
|
||||
updateFile(gen.id, file.id, { id: file.id, data })
|
||||
const data = safeJsonParse(doc.getText())
|
||||
if (data !== undefined) {
|
||||
updateFile(gen.id, file.id, { id: file.id, data })
|
||||
}
|
||||
}
|
||||
ignoreChange.current = false
|
||||
setError(null)
|
||||
@@ -211,7 +213,7 @@ export function SchemaGenerator({ gen, allowedVersions }: Props) {
|
||||
setShareShown(true)
|
||||
} else if (doc) {
|
||||
setShareLoading(true)
|
||||
shareSnippet(gen.id, version, JSON.parse(doc.getText()), previewShown)
|
||||
shareSnippet(gen.id, version, doc.getText(), previewShown)
|
||||
.then(({ id, length, compressed, rate }) => {
|
||||
Analytics.createSnippet(gen.id, id, version, length, compressed, rate)
|
||||
const url = `${location.origin}/${gen.url}/?${SHARE_KEY}=${id}`
|
||||
|
||||
@@ -5,7 +5,7 @@ import { getProjectData, useLocale, useProject, useStore, useVersion } from '../
|
||||
import { useAsync } from '../../hooks/index.js'
|
||||
import { checkVersion } from '../../services/Versions.js'
|
||||
import { Store } from '../../Store.js'
|
||||
import { iterateWorld2D, randomSeed, stringToColor } from '../../Utils.js'
|
||||
import { iterateWorld2D, randomSeed, safeJsonParse, stringToColor } from '../../Utils.js'
|
||||
import { Btn, BtnMenu, NumberInput } from '../index.js'
|
||||
import type { ColormapType } from './Colormap.js'
|
||||
import { getColormap } from './Colormap.js'
|
||||
@@ -32,7 +32,7 @@ export const BiomeSourcePreview = ({ docAndNode, shown }: PreviewProps) => {
|
||||
const [focused2, setFocused2] = useState<string[]>([])
|
||||
|
||||
const text = docAndNode.doc.getText()
|
||||
const data = JSON.parse(text)
|
||||
const data = safeJsonParse(text) ?? {}
|
||||
const type: string = data?.generator?.biome_source?.type?.replace(/^minecraft:/, '') ?? ''
|
||||
const hasRandomness = type === 'multi_noise' || type === 'the_end'
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import { useVersion } from '../../contexts/index.js'
|
||||
import { useAsync } from '../../hooks/useAsync.js'
|
||||
import { AsyncCancel } from '../../hooks/useAsyncFn.js'
|
||||
import { getResources, ResourceWrapper } from '../../services/Resources.js'
|
||||
import { safeJsonParse } from '../../Utils.js'
|
||||
import type { PreviewProps } from './index.js'
|
||||
import { InteractiveCanvas3D } from './InteractiveCanvas3D.jsx'
|
||||
|
||||
@@ -18,7 +19,7 @@ export const BlockStatePreview = ({ docAndNode, shown }: PreviewProps) => {
|
||||
const { value: resources } = useAsync(async () => {
|
||||
if (!shown) return AsyncCancel
|
||||
const resources = await getResources(version)
|
||||
const definition = BlockDefinition.fromJson(JSON.parse(text))
|
||||
const definition = BlockDefinition.fromJson(safeJsonParse(text) ?? {})
|
||||
const wrapper = new ResourceWrapper(resources, {
|
||||
getBlockDefinition(id) {
|
||||
if (id.equals(PREVIEW_ID)) return definition
|
||||
|
||||
@@ -2,7 +2,7 @@ import { BlockPos, ChunkPos, LegacyRandom, PerlinNoise } from 'deepslate'
|
||||
import type { mat3 } from 'gl-matrix'
|
||||
import { useCallback, useMemo, useRef, useState } from 'preact/hooks'
|
||||
import { useLocale, useVersion } from '../../contexts/index.js'
|
||||
import { computeIfAbsent, iterateWorld2D, randomSeed } from '../../Utils.js'
|
||||
import { computeIfAbsent, iterateWorld2D, randomSeed, safeJsonParse } from '../../Utils.js'
|
||||
import { Btn } from '../index.js'
|
||||
import type { PlacedFeature, PlacementContext } from './Decorator.js'
|
||||
import { decorateChunk } from './Decorator.js'
|
||||
@@ -50,7 +50,7 @@ export const DecoratorPreview = ({ docAndNode, shown }: PreviewProps) => {
|
||||
}, [])
|
||||
const onDraw = useCallback(function onDraw(transform: mat3) {
|
||||
if (!ctx.current || !imageData.current || !shown) return
|
||||
const data = JSON.parse(text)
|
||||
const data = safeJsonParse(text) ?? {}
|
||||
iterateWorld2D(imageData.current, transform, (x, y) => {
|
||||
const pos = ChunkPos.create(Math.floor(x / 16), Math.floor(-y / 16))
|
||||
const features = computeIfAbsent(chunkFeatures, `${pos[0]} ${pos[1]}`, () => decorateChunk(pos, data, context))
|
||||
|
||||
@@ -6,7 +6,7 @@ import { getProjectData, useLocale, useProject, useVersion } from '../../context
|
||||
import { useAsync } from '../../hooks/useAsync.js'
|
||||
import { useLocalStorage } from '../../hooks/useLocalStorage.js'
|
||||
import { Store } from '../../Store.js'
|
||||
import { iterateWorld2D, randomSeed } from '../../Utils.js'
|
||||
import { iterateWorld2D, randomSeed, safeJsonParse } from '../../Utils.js'
|
||||
import { Btn, BtnMenu, NumberInput } from '../index.js'
|
||||
import type { ColormapType } from './Colormap.js'
|
||||
import { getColormap } from './Colormap.js'
|
||||
@@ -33,7 +33,7 @@ export const DensityFunctionPreview = ({ docAndNode, shown }: PreviewProps) => {
|
||||
|
||||
const { value: df } = useAsync(async () => {
|
||||
await DEEPSLATE.loadVersion(version, getProjectData(project))
|
||||
const df = DEEPSLATE.loadDensityFunction(JSON.parse(text), minY, height, seed)
|
||||
const df = DEEPSLATE.loadDensityFunction(safeJsonParse(text) ?? {}, minY, height, seed)
|
||||
return df
|
||||
}, [version, project, minY, height, seed, text])
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { useMemo, useRef, useState } from 'preact/hooks'
|
||||
import { useLocale, useVersion } from '../../contexts/index.js'
|
||||
import { useAsync } from '../../hooks/useAsync.js'
|
||||
import { checkVersion, fetchAllPresets, fetchItemComponents } from '../../services/index.js'
|
||||
import { clamp, jsonToNbt, randomSeed } from '../../Utils.js'
|
||||
import { clamp, jsonToNbt, randomSeed, safeJsonParse } from '../../Utils.js'
|
||||
import { Btn, BtnMenu, NumberInput } from '../index.js'
|
||||
import { ItemDisplay } from '../ItemDisplay.jsx'
|
||||
import { ItemDisplay1204 } from '../ItemDisplay1204.jsx'
|
||||
@@ -40,10 +40,7 @@ export const LootTablePreview = ({ docAndNode }: PreviewProps) => {
|
||||
return []
|
||||
}
|
||||
const [itemTags, lootTables, itemComponents, enchantments, enchantmentTags] = dependencies
|
||||
let table = {}
|
||||
try {
|
||||
table = JSON.parse(text)
|
||||
} catch (e) {}
|
||||
const table = safeJsonParse(text) ?? {}
|
||||
if (use1204) {
|
||||
return generateLootTable1204(table, {
|
||||
version, seed, luck, daytime, weather,
|
||||
|
||||
@@ -5,6 +5,7 @@ import { useVersion } from '../../contexts/index.js'
|
||||
import { useAsync } from '../../hooks/useAsync.js'
|
||||
import { AsyncCancel } from '../../hooks/useAsyncFn.js'
|
||||
import { getResources, ResourceWrapper } from '../../services/Resources.js'
|
||||
import { safeJsonParse } from '../../Utils.js'
|
||||
import type { PreviewProps } from './index.js'
|
||||
import { InteractiveCanvas3D } from './InteractiveCanvas3D.jsx'
|
||||
|
||||
@@ -19,7 +20,7 @@ export const ModelPreview = ({ docAndNode, shown }: PreviewProps) => {
|
||||
const { value: resources } = useAsync(async () => {
|
||||
if (!shown) return AsyncCancel
|
||||
const resources = await getResources(version)
|
||||
const blockModel = BlockModel.fromJson(JSON.parse(text))
|
||||
const blockModel = BlockModel.fromJson(safeJsonParse(text) ?? {})
|
||||
blockModel.flatten(resources)
|
||||
const wrapper = new ResourceWrapper(resources, {
|
||||
getBlockDefinition(id) {
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { mat3 } from 'gl-matrix'
|
||||
import { useCallback, useMemo, useRef, useState } from 'preact/hooks'
|
||||
import { useLocale } from '../../contexts/index.js'
|
||||
import { Store } from '../../Store.js'
|
||||
import { iterateWorld2D, randomSeed } from '../../Utils.js'
|
||||
import { iterateWorld2D, randomSeed, safeJsonParse } from '../../Utils.js'
|
||||
import { Btn } from '../index.js'
|
||||
import type { ColormapType } from './Colormap.js'
|
||||
import { getColormap } from './Colormap.js'
|
||||
@@ -19,7 +19,7 @@ export const NoisePreview = ({ docAndNode, shown }: PreviewProps) => {
|
||||
|
||||
const noise = useMemo(() => {
|
||||
const random = XoroshiroRandom.create(seed)
|
||||
const params = NoiseParameters.fromJson(JSON.parse(text))
|
||||
const params = NoiseParameters.fromJson(safeJsonParse(text) ?? {})
|
||||
return new NormalNoise(random, params)
|
||||
}, [text, seed])
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import { getProjectData, useLocale, useProject, useVersion } from '../../context
|
||||
import { useAsync } from '../../hooks/index.js'
|
||||
import { fetchRegistries } from '../../services/index.js'
|
||||
import { Store } from '../../Store.js'
|
||||
import { iterateWorld2D, randomSeed } from '../../Utils.js'
|
||||
import { iterateWorld2D, randomSeed, safeJsonParse } from '../../Utils.js'
|
||||
import { Btn, BtnInput, BtnMenu, ErrorPanel } from '../index.js'
|
||||
import type { ColormapType } from './Colormap.js'
|
||||
import { getColormap } from './Colormap.js'
|
||||
@@ -26,7 +26,7 @@ export const NoiseSettingsPreview = ({ docAndNode, shown }: PreviewProps) => {
|
||||
const text = docAndNode.doc.getText()
|
||||
|
||||
const { value, error } = useAsync(async () => {
|
||||
const data = JSON.parse(text)
|
||||
const data = safeJsonParse(text) ?? {}
|
||||
await DEEPSLATE.loadVersion(version, getProjectData(project))
|
||||
const biomeSource = { type: 'fixed', biome }
|
||||
await DEEPSLATE.loadChunkGenerator(data, biomeSource, seed)
|
||||
|
||||
@@ -4,7 +4,7 @@ import { useLocale, useVersion } from '../../contexts/index.js'
|
||||
import { useAsync } from '../../hooks/useAsync.js'
|
||||
import type { VersionId } from '../../services/index.js'
|
||||
import { checkVersion, fetchAllPresets } from '../../services/index.js'
|
||||
import { jsonToNbt } from '../../Utils.js'
|
||||
import { jsonToNbt, safeJsonParse } from '../../Utils.js'
|
||||
import { Btn, BtnMenu } from '../index.js'
|
||||
import { ItemDisplay } from '../ItemDisplay.jsx'
|
||||
import type { PreviewProps } from './index.js'
|
||||
@@ -30,13 +30,13 @@ export const RecipePreview = ({ docAndNode }: PreviewProps) => {
|
||||
}, [])
|
||||
|
||||
const text = docAndNode.doc.getText()
|
||||
const recipe = JSON.parse(text)
|
||||
const recipe = safeJsonParse(text) ?? {}
|
||||
const items = useMemo<Map<Slot, ItemStack>>(() => {
|
||||
return placeItems(version, recipe, animation, itemTags ?? new Map())
|
||||
}, [text, animation, itemTags])
|
||||
|
||||
const gui = useMemo(() => {
|
||||
const type = recipe.type?.replace(/^minecraft:/, '')
|
||||
const type = recipe?.type?.replace(/^minecraft:/, '')
|
||||
if (type === 'smelting' || type === 'blasting' || type === 'smoking' || type === 'campfire_cooking') {
|
||||
return '/images/furnace.png'
|
||||
} else if (type === 'stonecutting') {
|
||||
|
||||
@@ -5,7 +5,7 @@ import { useCallback, useMemo, useRef, useState } from 'preact/hooks'
|
||||
import { useLocale, useVersion } from '../../contexts/index.js'
|
||||
import { useAsync } from '../../hooks/useAsync.js'
|
||||
import type { Color } from '../../Utils.js'
|
||||
import { computeIfAbsent, iterateWorld2D, randomSeed, stringToColor } from '../../Utils.js'
|
||||
import { computeIfAbsent, iterateWorld2D, randomSeed, safeJsonParse, stringToColor } from '../../Utils.js'
|
||||
import { Btn } from '../index.js'
|
||||
import { featureColors } from './Decorator.js'
|
||||
import { DEEPSLATE } from './Deepslate.js'
|
||||
@@ -21,7 +21,7 @@ export const StructureSetPreview = ({ docAndNode, shown }: PreviewProps) => {
|
||||
|
||||
const { value: structureSet } = useAsync(async () => {
|
||||
await DEEPSLATE.loadVersion(version)
|
||||
const structureSet = DEEPSLATE.loadStructureSet(JSON.parse(text), seed)
|
||||
const structureSet = DEEPSLATE.loadStructureSet(safeJsonParse(text) ?? {}, seed)
|
||||
return structureSet
|
||||
}, [text, version, seed])
|
||||
|
||||
|
||||
Reference in New Issue
Block a user