PROPOSAL: Richer Error Object

249 views
Skip to first unread message

Yehuda Katz

unread,
May 17, 2012, 2:49:43 PM5/17/12
to collect...@googlegroups.com
It's pretty common (but not universal) to want to include error information on a per-field basis.

I'd like to propose that in addition to the `error` (singular) key, an `errors` key could be provided, which would include a number of errors, with the values being `error` objects formatted as already specified.

I would also like error to optionally be an Array of errors:

{ "collection" :
  {
    "version" : "1.0",
    "href" : "http://example.org/friends/",
    
    "errors" : {
      {
        "password": [{
          "title": "Validation Error",
          "code": "X422",
          "message": "Must be at least 6 characters"
        }, {
          "title": "Validation Error",
          "code": "X422",
          "message": "Must contain at least one number"
        }],
        "name": {
          "title": "Validation Error",
          "code": "X422",
          "message": "Must not be blank"
        }
      }
    }
  } 
}

At present, the spec only allows one error, and makes all fields optional. I think we should specifically allow a string as the value of a message object, so the following would be semantically equivalent:

{ "collection" :
  {
    "version" : "1.0",
    "href" : "http://example.org/friends/",
    
    "errors" : {
      "password": [
        "Must have at least six characters",
        "Must have a symbol"
      ],
      "name": "Must not be blank"
    }
  }
}

and

{ "collection" :
  {
    "version" : "1.0",
    "href" : "http://example.org/friends/",
    
    "errors" : {
      "password": [
        { "message": "Must have at least six characters" },
        { "message": "Must have a symbol" }
      ],
      "name": { "message": "Must not be blank" }
    }
  }
}


Yehuda Katz
(ph) 718.877.1325

Steve Klabnik

unread,
May 17, 2012, 2:57:53 PM5/17/12
to collect...@googlegroups.com
I like it. This is certainly a weakness of the media type, as
discussed earlier, and this pretty much matches what I'd expect.

mca

unread,
May 17, 2012, 3:03:51 PM5/17/12
to collect...@googlegroups.com
Yehuda:

Yes, I think the error collection is a good idea. It's come up before, too.  So, in the case of generic clients, when they process the errors collection, they will need to first check to see if each object is an array or a single object and then process accordingly.

On the second point (optionally supporting only a string for the error object), I am not yet convinced this is a good idea. It adds more processing work for the client (checking to see if it's an object or a simple string; assuming that if it's a simple string it's a message and not a title or code) without any advantage I can see. This also runs the risk of breaking existing clients unless this mod is only used for the "errors" collection. 

Any use cases, other arguments you can provide in support of this change? 
Anyone want to make the case we should break existing clients for this change? 

Yehuda Katz

unread,
May 17, 2012, 3:14:11 PM5/17/12
to collect...@googlegroups.com

Yehuda Katz
(ph) 718.877.1325


On Thu, May 17, 2012 at 12:03 PM, mca <m...@amundsen.com> wrote:
Yehuda:

Yes, I think the error collection is a good idea. It's come up before, too.  So, in the case of generic clients, when they process the errors collection, they will need to first check to see if each object is an array or a single object and then process accordingly.

On the second point (optionally supporting only a string for the error object), I am not yet convinced this is a good idea. It adds more processing work for the client (checking to see if it's an object or a simple string; assuming that if it's a simple string it's a message and not a title or code) without any advantage I can see. This also runs the risk of breaking existing clients unless this mod is only used for the "errors" collection. 

Any use cases, other arguments you can provide in support of this change? 
Anyone want to make the case we should break existing clients for this change? 

Backwards compatibility is a good reason not to break it. The benefits are:
  • non-gzipped size (perhaps not very important)
  • human readability (useful, but not critical for debugging)

mca

unread,
May 17, 2012, 3:33:08 PM5/17/12
to collect...@googlegroups.com
<snip>
Backwards compatibility is a good reason not to break it.  
</snip>
It is for the client apps i've already built and have running!

size is very minor here.
w/ so many other objects and arrays, i am not convinced breaking this one is warranted as a human readability issue.

Eric Elliott

unread,
Jan 2, 2013, 8:17:20 PM1/2/13
to collect...@googlegroups.com

w/ so many other objects and arrays, i am not convinced breaking this one is warranted as a human readability issue.

Could an errors array be a non-breaking extension?

- Eric

Mike Amundsen

unread,
Jan 2, 2013, 9:41:27 PM1/2/13
to collect...@googlegroups.com

Eric Elliott

unread,
Jan 3, 2013, 6:31:56 PM1/3/13
to collect...@googlegroups.com
Oh great! Not sure how I overlooked that.

Johnathon Wright

unread,
Feb 26, 2014, 5:56:05 PM2/26/14
to collect...@googlegroups.com, wyc...@gmail.com
I'm looking at adding this extension or something like it to my fork of the collection-json fork. Why wouldn't you want the errors in the template?  Are there any use-cases where there would be an error _not_ related to submitting a form? Authorization comes to mind, but for those instances you could easily use the existing "error" element. And HTTP already has a way to handle that...

jw


----------
Johnathon Wright
Web Application Consultant

plus: j...@mustmodify.com
skype: johnathonwright
yahoo: johnathonewright
cell: 337 326 3121

http://www.mustmodify.com/

mca

unread,
Feb 26, 2014, 6:02:14 PM2/26/14
to collect...@googlegroups.com, Yehuda Katz
IIUYC:
templates are sending from client to server. 
errors are for sending from server to client.

do you mean you want to describe constraints on inputs and what error message to show if the constraints are not met?

"template" : {
  data:[
    {"name":uszipcode", value:"", "prompt":"Zip:","regex":"^\d{5}(?:[-\s]\d{4})?$", "regexPrompt":"Invalid Zip, try again"}
  ]
}

or are you thinking of something else?



mca

--
You received this message because you are subscribed to the Google Groups "Collection+JSON" group.
To unsubscribe from this group and stop receiving emails from it, send an email to collectionjso...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Johnathon Wright

unread,
Feb 26, 2014, 6:39:13 PM2/26/14
to collect...@googlegroups.com, Yehuda Katz
it's true that errors are coming from the server... but in the case of a response including an error, it is coming (presumably) as a response to having submitted via a template...

Similar to what you wrote, but I was thinking:

{
    "collection": {
        "href": "/force-users",
        "template": {
            "data": [
                {
                    "name": "name",
                    "value": "Darth Sirius Black",
                    "errors": [
                       "Name can not begin with Darth for light-side users.",
                       "Name must not have three words unless you are Lee Harvey Oswald."
                       ]
                },                    
                {
                    "name": "force-alignment",
                    "options": [
                        {
                            "prompt": "Dark Side",
                            "value": "dark"
                        },
                        {
                            "prompt": "Light Side",
                            "value": "light"
                        }
                    ]
                }
            ]
        }
    }
}

mca

unread,
Feb 26, 2014, 9:46:44 PM2/26/14
to collect...@googlegroups.com, Yehuda Katz
I see (i think).

i see some error messages here but not sure how to deal with them. are these just warnings to display in teh UI? or something to display *in response* to user input?

Johnathon Wright

unread,
Feb 27, 2014, 9:15:58 AM2/27/14
to collect...@googlegroups.com, Yehuda Katz
I'm sorry that this isn't clear. 

>> i see some error messages here but not sure how to deal with them. 
>> are these just warnings to display in teh UI? 

That is certainly one way they could be used.

>> or something to display *in response* to user input?

I'm not sure how those are different.

These are errors that explain why the submission failed.  Let me be more explicit.

As a user,
I want to register as a force-user
so that I can whatever.

When I go to the force-users list
Then I should have the option of adding myself using the parameters in the template


GET /force-user.json

200: OK

{
    "collection": {
        "href": "/force-users",
        "items": [
            {
                "data": 
                [
                    "name": "Yoda",
                    "alignment": "light"                    
                ]
            },
            {
                "data": 
                [
                    "name": "Obi-Wan",
                    "alignment": "light"                    
                ]
            }]
       "template": {
            "data": [
                {
                    "name": "name",
                    "required": "true"
                },                    
                {
                    "name": "alignment",
                    "required": "true"
                    "options":            /* the list of acceptable values */
                    [
                       {
                           "prompt": "Dark Side",
                           "value": "dark"
                       },
                       {
                           "prompt": "Light Side",
                           "value": "light"
                       },
                    ]
                }
            ]
        }
    }
}


POST /force-users.json, {"name": "Darth Serious", "alignment": "light"}

200: OK ( your request was received and processed, but no resource was created )

{
    "collection": {
        "href": "/force-users.json",
        "items": [ /* as to whether there should be items here, I would guess not... */ ]
        "template": {
            "data": [
                {
                    "name": "name",
                    "value": "Darth Sirius Black",  /* the value received by the server */
                    "required": true,
                    "errors": [
                       "Name can not begin with Darth for light-side users.",
                       "Name must not have three words unless you are Lee Harvey Oswald."
                       ]
                },                    
                {
                    "name": "alignment",
                    "value": "light",           /* the value received by the server */
                    "required": "true",
                    "options": [                   /* the list of acceptable values */
                        {
                            "prompt": "Dark Side",   
                            "value": "dark"  
                        },
                        {
                            "prompt": "Light Side",
                            "value": "light"

                        }
                    ]
                }
            ]
        }
    }
}

So in answer to your question, it is feedback to the user that they have submitted information that fails validation. Their submission did not result in a 201 (or 301, depending on your implementation.) They must re-submit if they want to create a resource.


mca

unread,
Feb 27, 2014, 9:46:49 AM2/27/14
to collect...@googlegroups.com
OK, i get it now - you want to return the template *in response to an error*

yeah - i can see that as a possibility. my _suggestion_ would be to return both the template and the error object in this case. use the error object to alert the client app and the template can be used to represent the inputs w/ additional information on how to fix things (using the new "errors:[]" array). but that's an implementation decision you can make on your own.

also, i would NOT return 200 OK if the resource creation failed. I'd return 400 instead.


Johnathon Wright

unread,
Feb 27, 2014, 3:51:42 PM2/27/14
to collect...@googlegroups.com
Please explain why there would be value in sending the errors back in two places?

 
also, i would NOT return 200 OK if the resource creation failed. I'd return 400 instead.

I could be wrong, but by "malformed request" I thought they meant "What you sent doesn't look like a valid HTTP get / post / whatever... it just looks like ... uh ... noise." rather than "I do not like green eggs and ham, but thinks for your perfectly valid HTTP request. Try white-and-yellow eggs instead and that should be ok."

mca

unread,
Feb 27, 2014, 5:12:17 PM2/27/14
to collect...@googlegroups.com
400 is a protocol-level response ("yeah, that thing you just tried to do - nope!")

the body is an application-level response ("so, the reason i rejected your request is that you failed to include a hat size")


--

Johnathon Wright

unread,
Mar 13, 2014, 9:31:24 AM3/13/14
to collect...@googlegroups.com
I changed the subject to avoid being OT.

On further reading, 403 seems to be the correct response.

The server understood the request, but is refusing to fulfill it. Authorization will not help and the request SHOULD NOT be repeated. If the request method was not HEAD and the server wishes to make public why the request has not been fulfilled, it SHOULD describe the reason for the refusal in the entity. If the server does not wish to make this information available to the client, the status code 404 (Not Found) can be used instead.

400 is "you are not speaking my language"
403 is "you are speaking my language. In response, my answer is no."

http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.4
Reply all
Reply to author
Forward
0 new messages