Skip to content

Commit

Permalink
Include real type names client-side error messages
Browse files Browse the repository at this point in the history
We already send `debugName` property in type metadata for this purpose.
Type hash is also included as it might also be useful
  • Loading branch information
exyi committed Nov 11, 2023
1 parent 1e179e2 commit bca66b5
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -248,16 +248,19 @@ type TypeMap = {
}

type DynamicTypeMetadata = {
debugName?: string,
type: "dynamic"
}

type ObjectTypeMetadata = {
type: "object",
debugName?: string,
properties: { [prop: string]: PropertyMetadata }
}

type EnumTypeMetadata = {
type: "enum",
debugName?: string,
values: { [name: string]: number },
isFlags?: boolean
}
Expand Down
6 changes: 3 additions & 3 deletions src/Framework/Framework/Resources/Scripts/metadata/coercer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { CoerceError } from "../shared-classes";
import { keys } from "../utils/objects";
import { tryCoerceEnum } from "./enums";
import { primitiveTypes } from "./primitiveTypes";
import { getObjectTypeInfo, getTypeInfo } from "./typeMap";
import { formatTypeName, getObjectTypeInfo, getTypeInfo } from "./typeMap";

/**
* Validates type of value
Expand Down Expand Up @@ -45,7 +45,7 @@ export function tryCoerce(value: any, type: TypeDefinition | null | undefined, o
}
}
}
return new CoerceError(`Unsupported type metadata ${JSON.stringify(type)}!`);
return new CoerceError(`Unsupported type metadata ${formatTypeName(type)}!`);
}

const result = core();
Expand Down Expand Up @@ -100,7 +100,7 @@ function tryCoerceArray(value: any, innerType: TypeDefinition, originalValue: an
return { value: items, wasCoerced: true };
}
}
return new CoerceError(`Value '${JSON.stringify(value)}' is not an array of type '${JSON.stringify(innerType)}'.`);
return new CoerceError(`Value '${JSON.stringify(value)}' is not an array of type '${formatTypeName(innerType)}'.`);
}

function tryCoercePrimitiveType(value: any, type: string): CoerceResult {
Expand Down
23 changes: 23 additions & 0 deletions src/Framework/Framework/Resources/Scripts/metadata/typeMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,26 @@ export function areObjectTypesEqual(currentValue: any, newVal: any): boolean {
}
return false;
}


export function formatTypeName(type: TypeDefinition, prefix = "", suffix = "") {
if (!compileConstants.debug)
return JSON.stringify(type)

if (typeof type === "string") {
let debugName = types[type]?.debugName
if (debugName)
return `${prefix}${debugName}${suffix} (${prefix}${type}${suffix})`
else
return prefix + type + suffix
}
if (Array.isArray(type)) {
return formatTypeName(type[0], prefix, "[]" + suffix)
}
if (type.type == "nullable") {
return formatTypeName(type.inner, prefix, "?" + suffix)
}
if (type.type == "dynamic") {
return prefix + "dynamic" + suffix
}
}
4 changes: 2 additions & 2 deletions src/Framework/Framework/Resources/Scripts/state-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { createArray, defineConstantProperty, isPrimitive, keys } from "./utils/objects";
import { DotvvmEvent } from "./events";
import { extendToObservableArrayIfRequired } from "./serialization/deserialize"
import { areObjectTypesEqual, getObjectTypeInfo } from "./metadata/typeMap";
import { areObjectTypesEqual, formatTypeName, getObjectTypeInfo } from "./metadata/typeMap";
import { coerce } from "./metadata/coercer";
import { patchViewModel } from "./postback/updater";
import { hackInvokeNotifySubscribers } from "./utils/knockout";
Expand Down Expand Up @@ -166,7 +166,7 @@ class FakeObservableObject<T extends object> implements UpdatableObjectExtension
}
}
} else if (!isDynamic && p.indexOf("$") !== 0) {
logWarning("state-manager", `Unknown property '${p}' set on an object of type ${typeId}.`);
logWarning("state-manager", `Unknown property '${p}' set on an object of type ${formatTypeName(typeId)}.`);
}

this[internalPropCache][p] = newObs
Expand Down

0 comments on commit bca66b5

Please sign in to comment.