Skip to content

Conversation

@RajPrakash681
Copy link
Contributor

@RajPrakash681 RajPrakash681 commented Oct 21, 2025

Requirements

  • This PR has a title that briefly describes the work done including the ticket number. Ensure your PR title includes a conventional commit label (such as feat, fix, or chore, among others). See existing PR titles for inspiration.

If applicable

  • My work is based on designs, which are linked or shown either in the Jira ticket or the description below.
  • My work includes tests or is validated by existing tests.
  • I have updated the esm-framework mock to reflect any API changes I have made.

Summary

This PR fixes a crash in the Implementer Tools that occurred when hovering over configuration nodes that have _description at the tree level (for parent/container nodes) instead of only at the leaf level.

Problem

The OpenMRS config system supports descriptions at both tree and leaf levels:

  • Tree level: foo: { _description: "Controls the big Foo thing", bar: {...} }
  • Leaf level: foo: { _description: "A setting", _value: "val", _source: "default" }

However, the ConfigSubtree component was iterating over ALL keys in config objects, including metadata keys like _description, _validators, _type, etc., and trying to render them as config tree nodes. When it encountered a tree-level _description, it would:

  1. Try to render _description as a config property node
  2. Attempt to recursively process the string value as if it were a config object
  3. Call Object.entries("string value") which causes unexpected behavior and crashes

Issue

https://openmrs.atlassian.net/browse/O3-4898

@RajPrakash681
Copy link
Contributor Author

@denniskigen this one also

@denniskigen denniskigen requested a review from ibacher October 21, 2025 21:52
Copy link
Member

@ibacher ibacher left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we undo the changes to the en.json files, please?

@RajPrakash681 RajPrakash681 force-pushed the fix/implementer-tools-tree-description-crash branch from 8123176 to e477c92 Compare October 22, 2025 09:06
@RajPrakash681
Copy link
Contributor Author

@ibacher i have fixed the changes you asked to do

.filter(([key]) => !key.startsWith('_'))
.map(([key, value], i) => {
const thisPath = path.concat([key]);
const isLeaf = Object.hasOwn(value, '_value');
Copy link
Member

@denniskigen denniskigen Oct 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const isLeaf = Object.hasOwn(value, '_value');
const isLeaf = value && typeof value === 'object' && Object.hasOwn(value, '_value');

Can we add a type check here before calling Object.hasOwn()? It will throw a TypeError if called on null or undefined. Without a guard, hovering over or rendering a config node with a null/undefined value will crash. With this check, value && short-circuits when value is null or undefined, so we never reach the typeof or Object.hasOwn() calls. This prevents the TypeError.

@denniskigen
Copy link
Member

denniskigen commented Oct 23, 2025

Tangential, but can we fix the improper use of lodash.unset in editable-value.component.tsx?

lodash.unset() mutates the object in place and returns a boolean (true if property existed), not the modified object. The current code passes this boolean to setState():

temporaryConfigStore.setState(unset(temporaryConfigStore.getState(), ['config', ...path]) as any);

This corrupts the store state. Instead, we should clone first, mutate the clone, then pass the clone to setState():

const state = cloneDeep(temporaryConfigStore.getState());
unset(state, ['config', ...path]);
temporaryConfigStore.setState(state);

This follows immutable state update patterns and prevents store corruption when resetting config values to defaults.

@denniskigen denniskigen changed the title (fix) O3-4898 : Implementer tools: Prevent crash when hovering over tree-level (fix) O3-4898: Implementer tools: Prevent crash when hovering over tree-level descriptions Oct 23, 2025
@RajPrakash681
Copy link
Contributor Author

@denniskigen i have applied the changes
also can you please look at openmrs/openmrs-esm-patient-management#2058 and openmrs/openmrs-esm-form-engine-lib#653

@RajPrakash681
Copy link
Contributor Author

@denniskigen sir any updates on this

@RajPrakash681
Copy link
Contributor Author

@denniskigen sorry to tag you again wanted to hop you up about this what else i need to do?

RajPrakash681 and others added 7 commits October 27, 2025 23:53
- Add type checks before Object.hasOwn() to prevent TypeError on null/undefined values
- Fix improper use of lodash.unset by cloning state before mutation
- Follows immutable state update patterns to prevent store corruption
- Add tests to verify type guards prevent TypeError on null/undefined values
- Add tests to verify immutable state update pattern with lodash.unset
- Ensures changes follow best practices and prevent store corruption
… component

Adds type guards for _source and _description properties to prevent runtime crashes when
accessing metadata on non-leaf config nodes. Also removes unused parameters and adds explicit
TypeScript type annotations for better type safety.
Converts CRLF (Windows) line endings to LF (Unix) to match repository convention.
Previous tests were not canonical and did not test the component-level behavior. Rather,
they test implementation details. They also used non-canonical imports instead of Jest
globals and are not colocated properly to the code they were testing.
@denniskigen denniskigen force-pushed the fix/implementer-tools-tree-description-crash branch from 062ebca to d903639 Compare October 27, 2025 21:50
@denniskigen
Copy link
Member

@RajPrakash681 could you change your IDE's line endings from CRLF (Carriage Return + Line Field) to LF (Line Field) to align with the repo's conventions? That explains the spurious en.json file changes.

Copy link
Member

@denniskigen denniskigen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @RajPrakash681!

@denniskigen denniskigen merged commit 19a7954 into openmrs:main Oct 27, 2025
12 of 14 checks passed
@RajPrakash681
Copy link
Contributor Author

@RajPrakash681 could you change your IDE's line endings from CRLF (Carriage Return + Line Field) to LF (Line Field) to align with the repo's conventions? That explains the spurious en.json file
Sure!

@brandones
Copy link
Contributor

I don't know why this was allowed to be merged without a video or screenshot—the crash no longer happens, but the higher-level description elements do not get displayed.

image

@denniskigen
Copy link
Member

denniskigen commented Nov 4, 2025

I don't know why this was allowed to be merged without a video or screenshot—the crash no longer happens, but the higher-level description elements do not get displayed.

image

🤦🏼 should we revert it, @brandones?

@brandones
Copy link
Contributor

I didn't read the code, dunno what it does; up to you. I updated the ticket description to clarify that expectation.

@RajPrakash681
Copy link
Contributor Author

@denniskigen @brandones
Hello,

Sorry for any inconvenience caused by my message. I see that the crash issue has been fixed, but now the tree-level descriptions are not displaying as expected,

I am happy to look into fixing this display issue with the higher-level descriptions in the Implementer Tools. Please confirm if you would like me to take this up, and if you can provide any additional details or test cases that I should consider when working on this fix.

@RajPrakash681
Copy link
Contributor Author

also,Also, I didn’t expect this issue to occur because all the tests were passing earlier in the same manner. Sorry for the unexpected problem and any confusion it may have caused.

@brandones
Copy link
Contributor

@RajPrakash681 please see the ticket description and my screenshot above. If it is clear to you what is being asked, then yes please go ahead and fix it. If not, ask a clarifying question.

Also, I didn’t expect this issue to occur because all the tests were passing earlier in the same manner.

The tests were also passing when the bug was causing the UI to crash completely. I see you wrote a test that has nothing to do with the problem (no mention of _description). I imagine that it too would pass without your change. That said, tests are not a sufficient guide to whether things work or not; you need to actually think about it. Think, "What is this supposed to do? What should it look like when it's working?" If you can write a test that fails, and which should pass if the bug is fixed, TDD style, then that's great.

This is a large, complex application, and you can't expect to just throw AI at it and get correct results. You have to try to understand it a little bit, at least the little piece you're working on.

@denniskigen
Copy link
Member

denniskigen commented Nov 4, 2025

I just ran the allergies app locally and I can see the descriptions:

CleanShot 2025-11-04 at 22 29 05@2x

window.spaVersion returns 8.0.1-pre.3473-20251029.

@RajPrakash681
Copy link
Contributor Author

also I promise to be more thorough in understanding the requirements and testing my changes properly before submitting. Issues like this won't happen again from my side - I'll make sure to always verify the feature works end-to-end in the UI, not just that the code compiles.

I'll update here once I have a proper fix ready for review.

@RajPrakash681
Copy link
Contributor Author

RajPrakash681 commented Nov 4, 2025

image

@denniskigen i can see the description

@brandones
Copy link
Contributor

I just ran the allergies app locally and I can see the descriptions:

It's the descriptions of upper-level elements (so in that example, concepts) rather than leaf nodes that are problematic. The leaf node descriptions have always worked fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants