Skip to content

Commit 6eec8b4

Browse files
committed
Don't coerce empty arrays for merge when value is not an object, and improve logging
1 parent 479bc11 commit 6eec8b4

3 files changed

Lines changed: 14 additions & 11 deletions

File tree

lib/Onyx.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -236,12 +236,11 @@ function merge<TKey extends OnyxKey>(key: TKey, changes: OnyxMergeInput<TKey>):
236236
}
237237

238238
try {
239-
if (Array.isArray(existingValue) && existingValue.length === 0) {
240-
Logger.logAlert(`[ENSURE_BUGBOT] Onyx merge called on key "${key}" whose existing value is an empty array. Will coerce to object.`);
241-
}
242-
243239
const validChanges = mergeQueue[key].filter((change) => {
244-
const {isCompatible, existingValueType, newValueType} = utils.checkCompatibilityWithExistingValue(change, existingValue);
240+
const {isCompatible, existingValueType, newValueType, isEmptyArrayCoercion} = utils.checkCompatibilityWithExistingValue(change, existingValue);
241+
if (isEmptyArrayCoercion) {
242+
Logger.logAlert(`[ENSURE_BUGBOT] Onyx merge called on key "${key}" whose existing value is an empty array. Will coerce to object.`);
243+
}
245244
if (!isCompatible) {
246245
Logger.logAlert(logMessages.incompatibleUpdateAlert(key, 'merge', existingValueType, newValueType));
247246
}

lib/OnyxUtils.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1576,8 +1576,11 @@ function mergeCollectionWithPatches<TKey extends CollectionKeyBase>(
15761576
const cachedCollectionForExistingKeys = getCachedCollection(collectionKey, existingKeys);
15771577

15781578
const existingKeyCollection = existingKeys.reduce((obj: OnyxInputKeyValueMapping, key) => {
1579-
const {isCompatible, existingValueType, newValueType} = utils.checkCompatibilityWithExistingValue(resultCollection[key], cachedCollectionForExistingKeys[key]);
1579+
const {isCompatible, existingValueType, newValueType, isEmptyArrayCoercion} = utils.checkCompatibilityWithExistingValue(resultCollection[key], cachedCollectionForExistingKeys[key]);
15801580

1581+
if (isEmptyArrayCoercion) {
1582+
Logger.logAlert(`[ENSURE_BUGBOT] Onyx mergeCollection called on key "${key}" whose existing value is an empty array. Will coerce to object.`);
1583+
}
15811584
if (!isCompatible) {
15821585
Logger.logAlert(logMessages.incompatibleUpdateAlert(key, 'mergeCollection', existingValueType, newValueType));
15831586
return obj;

lib/utils.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -207,16 +207,17 @@ function formatActionName(method: string, key?: OnyxKey): string {
207207
}
208208

209209
/** validate that the update and the existing value are compatible */
210-
function checkCompatibilityWithExistingValue(value: unknown, existingValue: unknown): {isCompatible: boolean; existingValueType?: string; newValueType?: string} {
210+
function checkCompatibilityWithExistingValue(value: unknown, existingValue: unknown): {isCompatible: boolean; existingValueType?: string; newValueType?: string; isEmptyArrayCoercion?: boolean} {
211211
if (!existingValue || !value) {
212212
return {
213213
isCompatible: true,
214214
};
215215
}
216-
// Empty arrays are compatible with objects — PHP's json_encode produces []
217-
// for empty associative arrays that should be {}.
218-
if (Array.isArray(existingValue) && existingValue.length === 0 && !Array.isArray(value)) {
219-
return {isCompatible: true};
216+
// An empty array existing value is compatible with an object update.
217+
// PHP's json_encode produces [] for empty associative arrays that should be {}.
218+
const isObjectValue = typeof value === 'object' && !Array.isArray(value);
219+
if (Array.isArray(existingValue) && existingValue.length === 0 && isObjectValue) {
220+
return {isCompatible: true, isEmptyArrayCoercion: true};
220221
}
221222

222223
const existingValueType = Array.isArray(existingValue) ? 'array' : 'non-array';

0 commit comments

Comments
 (0)