Compare commits

...
Author SHA1 Message Date
Sonarly Claude Code 4f5eb62189 chore: improve monitoring for fix: add defensive null check for objects field in
Added a `console.error` log in `useLoadStaleMetadataEntities.ts` that fires when the `ObjectMetadataItems` query returns a response without the expected `objects` field. This log will appear in Sentry breadcrumbs (as a console error-level breadcrumb) before any downstream TypeError, providing critical diagnostic context: whether `result.data` itself was defined, and flagging the unexpected response shape.

This follows the same defensive pattern already used elsewhere in the same file (e.g., `isDefined(result.data?.getPageLayouts)` check on line 138, `isDefined(result.data?.findManyLogicFunctions)` on line 166). The metadata objects query was the only fetch in this file lacking such a guard.
2026-03-18 00:31:30 +00:00
Sonarly Claude Code 18ddbdff77 fix: add defensive null check for objects field in metadata query response
https://sonarly.com/issue/15790?type=bug

TypeError thrown when the GraphQL metadata query response lacks the expected `objects` field, crashing the Settings > Objects > New Field page during background metadata refresh.

Fix: Added optional chaining (`?.`) to the `objects` and `edges` property accesses in `mapPaginatedObjectMetadataItemsToObjectMetadataItems.ts` line 18.

**Before:** `pagedObjectMetadataItems?.objects.edges.map(...)`
**After:** `pagedObjectMetadataItems?.objects?.edges?.map(...)`

The original code used optional chaining only on `pagedObjectMetadataItems`, which protects against it being `null`/`undefined`. But if the GraphQL response is defined yet has an unexpected shape (e.g., partial response with `objects: undefined` due to server-side error, or the response object itself having a different structure in the production bundle), accessing `.objects` or `.edges` on `undefined` throws the observed `TypeError`.

The `?? []` fallback at the end of the expression was already designed to handle this case (return empty array when data is unavailable), but the intermediate property accesses threw before reaching it. Adding `?.` throughout the chain ensures the fallback works correctly for any level of missing data.

This is a minimal, safe change — when the response is well-formed (the normal case), behavior is identical. When malformed, instead of crashing with a TypeError, it gracefully returns an empty array.
2026-03-18 00:31:30 +00:00
2 changed files with 8 additions and 1 deletions
@@ -72,6 +72,13 @@ export const useLoadStaleMetadataEntities = () => {
fetchPolicy: 'network-only',
})
.then((result) => {
if (!isDefined(result.data?.objects)) {
console.error(
'ObjectMetadataItems query returned unexpected response shape',
{ hasData: isDefined(result.data) },
);
}
const compositeObjects =
mapPaginatedObjectMetadataItemsToObjectMetadataItems({
pagedObjectMetadataItems: result.data,
@@ -15,7 +15,7 @@ export const mapPaginatedObjectMetadataItemsToObjectMetadataItems = ({
ObjectMetadataItem,
'readableFields' | 'updatableFields'
>[] =
pagedObjectMetadataItems?.objects.edges.map((object) => {
pagedObjectMetadataItems?.objects?.edges?.map((object) => {
const labelIdentifierFieldMetadataId =
objectMetadataItemSchema.shape.labelIdentifierFieldMetadataId.parse(
object.node.labelIdentifierFieldMetadataId,