diff --git a/lib/Document.ts b/lib/Document.ts index a9f8ae003..4311ca022 100644 --- a/lib/Document.ts +++ b/lib/Document.ts @@ -335,7 +335,7 @@ Document.objectFromSchema = async function (object: any, model: Model, if (existsInSchema) { const {isValidType, matchedTypeDetails, typeDetailsArray} = utils.dynamoose.getValueTypeCheckResult(schema, value, genericKey, settings, {"standardKey": true, typeIndexOptionMap}); if (!isValidType) { - throw new Error.TypeMismatch(`Expected ${key} to be of type ${typeDetailsArray.map((detail) => detail.dynamicName ? detail.dynamicName() : detail.name.toLowerCase()).join(", ")}, instead found type ${typeof value}${typeDetailsArray.some((val) => val.name === "Constant") ? ` (${value})` : ""}.`); + throw new Error.TypeMismatch(`Expected ${key} to be of type ${typeDetailsArray.map((detail) => detail.dynamicName ? detail.dynamicName() : detail.name.toLowerCase()).join(", ")}, instead found type ${utils.type_name(value, typeDetailsArray)}.`); } else if (matchedTypeDetails.isSet || matchedTypeDetails.name.toLowerCase() === "model") { validParents.push({key, "infinite": true}); } else if (/*typeDetails.dynamodbType === "M" || */matchedTypeDetails.dynamodbType === "L") { diff --git a/lib/utils/index.ts b/lib/utils/index.ts index 7ccb1895c..21ac91439 100644 --- a/lib/utils/index.ts +++ b/lib/utils/index.ts @@ -9,6 +9,7 @@ import empty_function = require("./empty_function"); import object = require("./object"); import dynamoose = require("./dynamoose"); import all_elements_match from "./all_elements_match"; +import type_name from "./type_name"; export = { combine_objects, @@ -21,5 +22,6 @@ export = { array_flatten, empty_function, object, - dynamoose + dynamoose, + type_name }; diff --git a/lib/utils/type_name.ts b/lib/utils/type_name.ts new file mode 100644 index 000000000..f9c247bfc --- /dev/null +++ b/lib/utils/type_name.ts @@ -0,0 +1,16 @@ +import {DynamoDBSetTypeResult, DynamoDBTypeResult} from "../Schema"; + +// This function takes in a value and returns a user string for the type of that value. This function is mostly used to display type errors to users. +export default (value: any, typeDetailsArray: (DynamoDBTypeResult | DynamoDBSetTypeResult)[]): string => { + let str = ""; + if (value === null) { + str += "null"; + } else { + str += typeof value; + } + + // Add constant value to type name + str += typeDetailsArray.some((val) => val.name === "Constant") ? ` (${value})` : ""; + + return str; +}; diff --git a/test/unit/Document.js b/test/unit/Document.js index 10e4cb09a..bf34b9593 100644 --- a/test/unit/Document.js +++ b/test/unit/Document.js @@ -2750,6 +2750,11 @@ describe("Document", () => { return {"id": Number, "data": [{"type": Set, "schema": [Item]}, String]}; }, "error": new Error.ValidationError("Expected data to be of type Item Set, string, instead found type boolean.") + }, + { + "input": [{"id": 1, "data": null}, {"type": "toDynamo"}], + "schema": {"id": Number, "data": String}, + "error": new Error.ValidationError("Expected data to be of type string, instead found type null.") } ];