Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert error hash to object with helpful error rendering messages? #48

Closed
robacarp opened this issue Oct 12, 2019 · 3 comments
Closed

Comments

@robacarp
Copy link

robacarp commented Oct 12, 2019

Hello, and thanks for working on this project. I'm working to get some helpful error messages produced by schema validation and having to jump through some hoops:

  def steps_must_conform_to_schema
    steps.each.with_index do |step, index|
      schema_errors = SCHEMA.validate step

      if schema_errors.any?
        errors.add(
          "step #{index}",
          decode_schema_error(schema_errors.first)
        )
      end
    end
  end

  def decode_schema_error(error)
    messages = []

    error["details"].each do |error_type, details|
      case error_type
      when "missing_keys"
        messages << "is missing required keys #{details.join(", ")}"
      when "schema"
      end
    end

    messages.join ", "
  end

Would it be a useful enhancement to convert the error hash into an object which has rendering methods for building the plain text version of the error?

@robacarp
Copy link
Author

Here's a more complete error rendering method. I'm sure it's incomplete, but it's a start:

  def decode_json_schemer_errors(error)
    messages = []

    formatted_data_pointer = format_data_pointer error["data_pointer"]

    case error["type"]
    when "required"
      if error["details"].key? "missing_keys"
        messages << "#{formatted_data_pointer}is missing required keys #{error["details"]["missing_keys"].join(", ")}"
      else
        messages << "#{formatted_data_pointer}is missing required keys"
      end

    when "schema"
      if error["schema_pointer"] == "/additionalProperties"
        messages << "contains unrecognized property '#{formatted_data_pointer}'"
      else
        messages << "does not validate: schema_pointer=#{error["schema_pointer"]}"
      end

    when "string"
      messages << "property '#{formatted_data_pointer}' should be a string"
    when "boolean"
      messages << "property '#{formatted_data_pointer}' should be a boolean"
    when "integer"
      messages << "property '#{formatted_data_pointer}' should be a number"
    when "object"
      messages << "property '#{formatted_data_pointer}' should be an object"
    when "pattern"
      messages << "property '#{formatted_data_pointer}' does not match pattern: #{error["schema"]["pattern"]}"
    else
      messages << "does not validate: error_type=#{error["type"]}"
    end

    messages.flatten.join ", "
  end

  def format_data_pointer(data_pointer)
    data_pointer = data_pointer
      .sub(%r|^/|, '')   # remove leading /
      .sub('/', '.')     # convert / into .

    unless data_pointer.blank?
      data_pointer = data_pointer + ' '
    end

    data_pointer
  end

@davishmcclurg
Copy link
Owner

Thanks for the issue! I'll keep this in mind when I get around to implementing the latest draft's "output formatting": #2

@davishmcclurg
Copy link
Owner

I'll likely leave the errors as hashes with a more useful default error message.

leshill added a commit to leshill/json_schemer that referenced this issue Apr 28, 2020
This is based on a snippet of code offered by @robacarp in davishmcclurg#48. The code has
been cleaned up and tested and provides a standalone interface for converting
errors into a human readable message:

```ruby
errors = schema.validate({ 'a' => { 'x' => 1 } }).to_a
errors.map {|err| JSONSchemer::Errors.pretty err }
```

Longer term, an option can be introduced that allows the generation of the
message inline with the validation. For example, given the option `pretty:
true`, then on line 229 of `lib/json_schemer/schema/base.rb` (as of #a2a6df8),
the message could be added to the error hash:

```ruby
  error['message'] = JSONSchemer::Errors.pretty(error) if pretty
```
leshill added a commit to leshill/json_schemer that referenced this issue Apr 28, 2020
This is based on a snippet of code offered by @robacarp in davishmcclurg#48. The code has
been cleaned up and tested and provides a standalone interface for converting
errors into a human readable message:

```ruby
errors = schema.validate({ 'a' => { 'x' => 1 } }).to_a
errors.map {|err| JSONSchemer::Errors.pretty err }
```

Longer term, an option can be introduced that allows the generation of the
message inline with the validation. For example, given the option `pretty:
true`, then on line 229 of `lib/json_schemer/schema/base.rb` (as of #a2a6df8),
the message could be added to the error hash:

```ruby
  error['message'] = JSONSchemer::Errors.pretty(error) if pretty
```
leshill added a commit to leshill/json_schemer that referenced this issue Apr 28, 2020
This is based on a snippet of code offered by @robacarp in davishmcclurg#48. The code has
been cleaned up and tested and provides a standalone interface for converting
errors into a human readable message:

```ruby
errors = schema.validate({ 'a' => { 'x' => 1 } }).to_a
errors.map {|err| JSONSchemer::Errors.pretty err }
```

Longer term, an option can be introduced that allows the generation of the
message inline with the validation. For example, given the option `pretty:
true`, then on line 229 of `lib/json_schemer/schema/base.rb` (as of #a2a6df8),
the message could be added to the error hash:

```ruby
  error['message'] = JSONSchemer::Errors.pretty(error) if pretty
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants