From 6e72c30c6f1eac13309028b3e2aa3dffe80fac1f Mon Sep 17 00:00:00 2001 From: John Kastner Date: Thu, 9 Jul 2026 13:13:43 -0400 Subject: [PATCH 1/3] Nicer errors on "evaluate" with syntax errors in context/entities Signed-off-by: John Kastner --- .../policy-playground/PolicyPlayground.tsx | 23 ++++++-- tests/sandbox.test.tsx | 57 +++++++++++++++++++ 2 files changed, 74 insertions(+), 6 deletions(-) diff --git a/src/routes/policy-playground/PolicyPlayground.tsx b/src/routes/policy-playground/PolicyPlayground.tsx index fb85403..7932fca 100644 --- a/src/routes/policy-playground/PolicyPlayground.tsx +++ b/src/routes/policy-playground/PolicyPlayground.tsx @@ -100,15 +100,26 @@ export default function PolicyPlayground() { const evaluateInput = () => { const { policy, entities, context, principal, action, resource, schema } = uiState; const start = performance.now(); - let parsedEntities: EntityJson[] = []; - let parsedContext: Context = {}; + const setParseError = (e: unknown) => + setOutput({ + status: 'error', + message: t('issueAuthRequest.parseError'), + errors: [(e as Error).message], + warnings: [], + }); + let parsedEntities: EntityJson[]; + let parsedContext: Context; try { parsedEntities = JSON.parse(entities) as EntityJson[]; + } catch (e) { + setParseError(e); + return; + } + try { parsedContext = JSON.parse(context) as Context; - } catch (_e) { - // Fall through: let wasm produce the error if JSON is invalid. - parsedEntities = []; - parsedContext = {}; + } catch (e) { + setParseError(e); + return; } const result = isAuthorized({ principal, diff --git a/tests/sandbox.test.tsx b/tests/sandbox.test.tsx index a322912..b0419f9 100644 --- a/tests/sandbox.test.tsx +++ b/tests/sandbox.test.tsx @@ -7,6 +7,11 @@ import { IntlProvider } from 'react-intl'; import nestedMessages from '../src/translations/en.json'; import { flattenMessages } from '../src/util/flattenMessages'; import { getCedarVersion } from '@cedar-policy/cedar-wasm'; +import { + exportCedarPlaygroundDataToBase64, + PLAYGROUND_URL_FRAG_PREFIX, + CedarPlaygroundDataTransferObject, +} from '../src/playground-helpers'; const messages = flattenMessages(nestedMessages); @@ -84,4 +89,56 @@ describe('playground tests', () => { expect(cedarVersion).toBeDefined(); expect(cedarVersion).toEqual(expect.any(String)); }); + + it('should show error when entities JSON is invalid', async () => { + const dto: CedarPlaygroundDataTransferObject = { + interfaceVersion: 1, + cedarVersion: getCedarVersion(), + playgroundData: { + policy: 'permit(principal, action, resource);', + schema: '', + principal: { type: 'User', id: 'alice' }, + action: { type: 'Action', id: 'view' }, + resource: { type: 'Photo', id: 'photo1' }, + entities: 'not valid json [[[', + context: '{}', + isAVPFormat: false, + }, + }; + const exported = exportCedarPlaygroundDataToBase64(dto); + if ('error' in exported) throw new Error(exported.error); + window.location.hash = `#${PLAYGROUND_URL_FRAG_PREFIX}${exported.result}`; + + mountPlayground(); + fireEvent.click(screen.getByTestId('evaluate-button')); + await screen.findByText(/Invalid context or entities input/); + + window.location.hash = ''; + }); + + it('should show error when context JSON is invalid', async () => { + const dto: CedarPlaygroundDataTransferObject = { + interfaceVersion: 1, + cedarVersion: getCedarVersion(), + playgroundData: { + policy: 'permit(principal, action, resource);', + schema: '', + principal: { type: 'User', id: 'alice' }, + action: { type: 'Action', id: 'view' }, + resource: { type: 'Photo', id: 'photo1' }, + entities: '[]', + context: '{invalid context}', + isAVPFormat: false, + }, + }; + const exported = exportCedarPlaygroundDataToBase64(dto); + if ('error' in exported) throw new Error(exported.error); + window.location.hash = `#${PLAYGROUND_URL_FRAG_PREFIX}${exported.result}`; + + mountPlayground(); + fireEvent.click(screen.getByTestId('evaluate-button')); + await screen.findByText(/Invalid context or entities input/); + + window.location.hash = ''; + }); }); From 6318d73eb1e35b684ee70c7df6e28e4f204be3e4 Mon Sep 17 00:00:00 2001 From: John Kastner Date: Thu, 9 Jul 2026 14:01:35 -0400 Subject: [PATCH 2/3] finally Signed-off-by: John Kastner --- tests/sandbox.test.tsx | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/tests/sandbox.test.tsx b/tests/sandbox.test.tsx index b0419f9..0f93651 100644 --- a/tests/sandbox.test.tsx +++ b/tests/sandbox.test.tsx @@ -108,12 +108,13 @@ describe('playground tests', () => { const exported = exportCedarPlaygroundDataToBase64(dto); if ('error' in exported) throw new Error(exported.error); window.location.hash = `#${PLAYGROUND_URL_FRAG_PREFIX}${exported.result}`; - - mountPlayground(); - fireEvent.click(screen.getByTestId('evaluate-button')); - await screen.findByText(/Invalid context or entities input/); - - window.location.hash = ''; + try { + mountPlayground(); + fireEvent.click(screen.getByTestId('evaluate-button')); + await screen.findByText(/Invalid context or entities input/); + } finally { + window.location.hash = ''; + } }); it('should show error when context JSON is invalid', async () => { @@ -134,11 +135,12 @@ describe('playground tests', () => { const exported = exportCedarPlaygroundDataToBase64(dto); if ('error' in exported) throw new Error(exported.error); window.location.hash = `#${PLAYGROUND_URL_FRAG_PREFIX}${exported.result}`; - - mountPlayground(); - fireEvent.click(screen.getByTestId('evaluate-button')); - await screen.findByText(/Invalid context or entities input/); - - window.location.hash = ''; + try { + mountPlayground(); + fireEvent.click(screen.getByTestId('evaluate-button')); + await screen.findByText(/Invalid context or entities input/); + } finally { + window.location.hash = ''; + } }); }); From 4fda7a58567aca002faaa341907c7a8fd688a57f Mon Sep 17 00:00:00 2001 From: John Kastner Date: Thu, 9 Jul 2026 14:16:28 -0400 Subject: [PATCH 3/3] tweak Signed-off-by: John Kastner --- tests/sandbox.test.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/sandbox.test.tsx b/tests/sandbox.test.tsx index 0f93651..4bf0b71 100644 --- a/tests/sandbox.test.tsx +++ b/tests/sandbox.test.tsx @@ -108,11 +108,12 @@ describe('playground tests', () => { const exported = exportCedarPlaygroundDataToBase64(dto); if ('error' in exported) throw new Error(exported.error); window.location.hash = `#${PLAYGROUND_URL_FRAG_PREFIX}${exported.result}`; + const { unmount } = mountPlayground(); try { - mountPlayground(); fireEvent.click(screen.getByTestId('evaluate-button')); await screen.findByText(/Invalid context or entities input/); } finally { + unmount(); window.location.hash = ''; } }); @@ -135,11 +136,12 @@ describe('playground tests', () => { const exported = exportCedarPlaygroundDataToBase64(dto); if ('error' in exported) throw new Error(exported.error); window.location.hash = `#${PLAYGROUND_URL_FRAG_PREFIX}${exported.result}`; + const { unmount } = mountPlayground(); try { - mountPlayground(); fireEvent.click(screen.getByTestId('evaluate-button')); await screen.findByText(/Invalid context or entities input/); } finally { + unmount(); window.location.hash = ''; } });