Code Monkey home page Code Monkey logo

Comments (4)

ddenisenko avatar ddenisenko commented on July 25, 2024

the property on which the error occurred. currently it is not consistent, sometimes it's error.source.name, sometimes it's error.vp.name [1]

There is no such thing as "the property on which error occurred". Sometimes the error is not caused by any particular property, any particular facet etc.
The closest thing to what you want is the validation path - the mechanism designed to highlight the error source.

Let me provide an example of how to use this mechanism:

Here we define an invalid type:

var personType = ts.loadType( {
    type:"object",
    properties:{
        test : {
            type: "string[]",
            minItems:"blah"
        }
    }
})

Now lets try to find out the source(s) of the error:

var validationResult = personType.validateType();
if (!validationResult.isOk()) {
    validationResult.getErrors().forEach(function(error){
        console.log("Error [" + error.getMessage()
            + "] occurred at path ["
            + error.getValidationPathAsString() +"]")
    })
}

Here is the output:

Error ['minItems' value should be a number] occurred at path [test/minItems]

Here test/minItems is a path inside the type you validate pointing to the source.
Please note that the path can be unavailable in some cases, the type itself should be reported when this happens.

Note: you can use getValidationPath method to get the segments chain instead of the string

the constrain key that triggered the error. e.g. type, required, pattern, minLength, etc

It is recommended to use validation path, but if you wish to see the constraint and the error is caused by a constraint, you can obtain it as a source. For the example above:

var validationResult = personType.validateType();
if (!validationResult.isOk()) {
    validationResult.getErrors().forEach(function(error){
        console.log("Error [" + error.getMessage()
            + "] occurred at path ["
            + error.getValidationPathAsString() +"]")

        var errorSource = error.getSource();
        if (errorSource.facetName) {
            console.log("Facet name: " + errorSource.facetName())
        }
    })
}

Output:

Error ['minItems' value should be a number] occurred at path [test/minItems]
Facet name: minItems

the constrain value, e.g. string, true, [a-z]+, 1, etc

Same as above, it can happen that there is no facet involved, but if there is one you can obtain the value:

var validationResult = personType.validateType();
if (!validationResult.isOk()) {
    validationResult.getErrors().forEach(function(error){
        console.log("Error [" + error.getMessage()
            + "] occurred at path ["
            + error.getValidationPathAsString() +"]")

        var errorSource = error.getSource();
        if (errorSource.facetName) {
            console.log("Facet name: " + errorSource.facetName())
            console.log("Facet value: " + errorSource.value())
        }
    })
}

Output:

Error ['minItems' value should be a number] occurred at path [test/minItems]
Facet name: minItems
Facet value: blah

In case of the { type: [ 'string', 'integer' ] } illegal type there is no facet directly responsible for the error, so you will get no validation path and should report the type itself.
If you are really interested in the cause in this particular case, you can analyze the status being instance of RestrictionConflict, and get its error.getConflicting() restriction that conflicts with the other stack error.getStack().

[1] if the property is not available (i.e. single type), maybe it could be the name of the variable that was assigned to the type, e.g. personType in the 1st example

Copy-pasting the linked sample here to make it more clear:

import ts = require("raml-typesystem")

var personType = ts.loadType( {
    type: "string[]",
    minItems:3,
    maxItems:2
})

var isValid = personType.validateType();

In this example,

{
    type: "string[]",
    minItems:3,
    maxItems:2
}

is an initial type description, it could be RAML code instead.

The value of personType variable is an instance of an object, which is created by raml-typesystem library.

personType itself is a variable, you as a user created, it is totally unrelated to the raml-typesystem library, and in most languages the library would be having no access to this variable. So no, putting the name of the external user-created variable into the status being created by the library should not happen.

from raml-typesystem.

jstoiko avatar jstoiko commented on July 25, 2024

thanks for the pointers. your solution works fine for validation errors like pattern, maximum, minimum, however the results are not consistent for errors related to types.

For example:

  • if I pass a string to a type: 'integer', errorSource.facetName() returns should be integer and errorSource.value() returns true, I would expect to get type and integer respectively
  • if I pass a string to a type: 'number', errorSource.facetName() returns typeOf, I would expect it to return type
  • if I pass an integer to a type: 'string', errorSource.facetName() returns typeOf, I would expect it to return type
  • if I pass a string to a type: 'boolean', errorSource.facetName() returns typeOf, I would expect it to return type
  • if I pass a string to a type: 'unknown', errorSource.facetName() returns nothing and errorSource.value() returns !!!, I would expect to get type and unknown respectively
  • if I pass a number to a type: 'string | integer', errorSource.facetName() returns typeOf and errorSource.value() returns string, I would expect to get type and integer respectively

from raml-typesystem.

jstoiko avatar jstoiko commented on July 25, 2024

another slightly different one with dates:

  • if I pass a Sun, 28 Feb 2016 16:41:41 GMT to a type: 'date time', errorSource.facetName() returns should be datetime-only and errorSource.value() returns true, I expect -> type and datetime, not datetime-only which is the inputed type

from raml-typesystem.

ddenisenko avatar ddenisenko commented on July 25, 2024

@jstoiko facetName() and value() methods has meaning for the subclasses of FacetRestriction class. There is a big hierarchy of restrictions, and facet restrictions are only a part of it.

You can analyze and support the whole hierarchy if you want, but there is like 30 classes in there, and there are other sources, not only restrictions.

As I said, please use the error message and validation path to find out the source. If there is no path, report the issue to the current root.

from raml-typesystem.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.