Skip to content

Object as a validation error message #554

@ZBAGI

Description

@ZBAGI

Current design only allows string as a validation error message. That is problematic for the API's that would like to return validation rules, instead of compiled error message.

As an example lets take API that has to support multi-language front-ends but wants to not involve into back-end translations. Returning error json that contains all rules would be ideal solution. It allows front-end to compile error message to its own standards or change rules on run-time by catching them into file.

Here is example of ideal return error:

{
// ...
    "constraints": {
        "notInRage": {
              "min": 3,
              "max": 10
        },
        "notMatchingRegex": {
              "pattern": "^example"
        }
    }
//...
}

I have check source code and technically only think that stops it from being possible ( other then types of course ) is implementation of ValidationUtils.ts

Simple check if object then return it would make this feature possible.
Here is a little hack that i currently use:

class ErrorObject {
    [key: string]: any;

    public static create(objectError: object): any {
        const obj = new ErrorObject();
        // Ofically we return <any>, so typescript will not complain about not being <string>
        // in reality we return function that returns this class with everything that are provided by `objectError`
        // It has to be wrapped in function in order to satisfy ValidationUtils.replaceMessageSpecialTokens condition `if (message instanceof Function)`
        return () => Object.assign(obj, objectError);
    }
    
    public replace(...args: any[]) {
        // This is manatory as ValidationUtils.replaceMessageSpecialTokens calls this method to replace some string variables.
        // Without that it would throw an error
        return this;
    }
}

And here is usage:

export function MatchRegExp(pattern: string) {
   return function (object: Object, propertyName: string) {
       
        registerDecorator({
            name: "notMatchingRegex",
            target: object.constructor,
            propertyName: propertyName,
            constraints: [],
            options: {
                dismissDefaultMessages: true
            },
            validator: {
                validate(value: any, args: ValidationArguments) {
                    return new RegExp(pattern).test(value);
                },
                defaultMessage(validationArguments?: ValidationArguments) {
                    return ErrorObject.create({ pattern });
                }
            }
        });
   };
}

I would love to see this feature officially supported without my dirty hack.

Metadata

Metadata

Assignees

No one assigned

    Labels

    type: featureIssues related to new features.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions