<div dir="ltr"><div>Oh, I understood it a little differently. I took "<span style="font-size:12.8000001907349px">parsing of error messages here is not the way we’d like to solve this problem" as meaning that parsing them in their current ad-hoc, project-specific format is not the way we want to solve this (e.g. the way tempest does it). But if we had a structured way like the EC2 errors, it would be a much easier problem to solve.</span><br></div><div><span style="font-size:12.8000001907349px"><br></span></div><div><span style="font-size:12.8000001907349px">So either way we are still parsing the body, the only difference is that the parser no longer has to understand how to parse Neutron errors vs. Nova errors. It just needs to parse the standard "OpenStack error" format that we come up with.</span></div><div class="gmail_extra"><br><div class="gmail_quote"><br></div><div class="gmail_quote"><br></div><div class="gmail_quote">On Thu, Jan 29, 2015 at 12:04 PM, John Dickinson <span dir="ltr"><<a href="mailto:me@not.mn" target="_blank">me@not.mn</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I think there are two points. First, the original requirement (in the first email on this thread) is not what's wanted:<br>
<br>
"...looking at the response body and HTTP response code an external system can’t understand what exactly went wrong. And parsing of error messages here is not the way we’d like to solve this problem."<br>
<br>
So adding a response body to parse doesn't solve the problem. The request as I read it is to have a set of well-defined error codes to know what happens.<br>
<br>
Second, my response is a little tongue-in-cheek, because I think the IIS response codes are a perfect example of extending a common, well-known protocol with custom extensions that breaks existing clients. I would hate to see us do that.<br>
<br>
So if we can't subtly break http, and we can't have error response documents, then we're left with custom error codes in the particular response-code class. eg 461 SecurityGroupNotFound or 462 InvalidKeyName (from the original examples)<br>
<span class="HOEnZb"><font color="#888888"><br>
<br>
--John<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
<br>
<br>
<br>
<br>
<br>
> On Jan 29, 2015, at 11:39 AM, Brant Knudson <<a href="mailto:blk@acm.org">blk@acm.org</a>> wrote:<br>
><br>
><br>
><br>
> On Thu, Jan 29, 2015 at 11:41 AM, Sean Dague <<a href="mailto:sean@dague.net">sean@dague.net</a>> wrote:<br>
> Correct. This actually came up at the Nova mid cycle in a side<br>
> conversation with Ironic and Neutron folks.<br>
><br>
> HTTP error codes are not sufficiently granular to describe what happens<br>
> when a REST service goes wrong, especially if it goes wrong in a way<br>
> that would let the client do something other than blindly try the same<br>
> request, or fail.<br>
><br>
> Having a standard json error payload would be really nice.<br>
><br>
> {<br>
> fault: ComputeFeatureUnsupportedOnInstanceType,<br>
> messsage: "This compute feature is not supported on this kind of<br>
> instance type. If you need this feature please use a different instance<br>
> type. See your cloud provider for options."<br>
> }<br>
><br>
> That would let us surface more specific errors.<br>
><br>
> Today.... there is a giant hodgepodge - see:<br>
><br>
> <a href="https://github.com/openstack/tempest-lib/blob/master/tempest_lib/common/rest_client.py#L412-L424" target="_blank">https://github.com/openstack/tempest-lib/blob/master/tempest_lib/common/rest_client.py#L412-L424</a><br>
><br>
> <a href="https://github.com/openstack/tempest-lib/blob/master/tempest_lib/common/rest_client.py#L460-L492" target="_blank">https://github.com/openstack/tempest-lib/blob/master/tempest_lib/common/rest_client.py#L460-L492</a><br>
><br>
> Especially blocks like this:<br>
><br>
> if 'cloudServersFault' in resp_body:<br>
> message =<br>
> resp_body['cloudServersFault']['message']<br>
> elif 'computeFault' in resp_body:<br>
> message = resp_body['computeFault']['message']<br>
> elif 'error' in resp_body:<br>
> message = resp_body['error']['message']<br>
> elif 'message' in resp_body:<br>
> message = resp_body['message']<br>
><br>
> Standardization here from the API WG would be really great.<br>
><br>
> -Sean<br>
><br>
> On 01/29/2015 09:11 AM, Roman Podoliaka wrote:<br>
> > Hi Anne,<br>
> ><br>
> > I think Eugeniya refers to a problem, that we can't really distinguish<br>
> > between two different badRequest (400) errors (e.g. wrong security<br>
> > group name vs wrong key pair name when starting an instance), unless<br>
> > we parse the error description, which might be error prone.<br>
> ><br>
> > Thanks,<br>
> > Roman<br>
> ><br>
> > On Thu, Jan 29, 2015 at 6:46 PM, Anne Gentle<br>
> > <<a href="mailto:annegentle@justwriteclick.com">annegentle@justwriteclick.com</a>> wrote:<br>
> >><br>
> >><br>
> >> On Thu, Jan 29, 2015 at 10:33 AM, Eugeniya Kudryashova<br>
> >> <<a href="mailto:ekudryashova@mirantis.com">ekudryashova@mirantis.com</a>> wrote:<br>
> >>><br>
> >>> Hi, all<br>
> >>><br>
> >>><br>
> >>> Openstack APIs interact with each other and external systems partially by<br>
> >>> passing of HTTP errors. The only valuable difference between types of<br>
> >>> exceptions is HTTP-codes, but current codes are generalized, so external<br>
> >>> system can’t distinguish what actually happened.<br>
> >>><br>
> >>><br>
> >>> As an example two different failures below differs only by error message:<br>
> >>><br>
> >>><br>
> >>> request:<br>
> >>><br>
> >>> POST /v2/790f5693e97a40d38c4d5bfdc45acb09/servers HTTP/1.1<br>
> >>><br>
> >>> Host: <a href="http://192.168.122.195:8774" target="_blank">192.168.122.195:8774</a><br>
> >>><br>
> >>> X-Auth-Project-Id: demo<br>
> >>><br>
> >>> Accept-Encoding: gzip, deflate, compress<br>
> >>><br>
> >>> Content-Length: 189<br>
> >>><br>
> >>> Accept: application/json<br>
> >>><br>
> >>> User-Agent: python-novaclient<br>
> >>><br>
> >>> X-Auth-Token: 2cfeb9283d784cfba694f3122ef413bf<br>
> >>><br>
> >>> Content-Type: application/json<br>
> >>><br>
> >>><br>
> >>> {"server": {"name": "demo", "imageRef":<br>
> >>> "171c9d7d-3912-4547-b2a5-ea157eb08622", "key_name": "test", "flavorRef":<br>
> >>> "42", "max_count": 1, "min_count": 1, "security_groups": [{"name": "bar"}]}}<br>
> >>><br>
> >>> response:<br>
> >>><br>
> >>> HTTP/1.1 400 Bad Request<br>
> >>><br>
> >>> Content-Length: 118<br>
> >>><br>
> >>> Content-Type: application/json; charset=UTF-8<br>
> >>><br>
> >>> X-Compute-Request-Id: req-a995e1fc-7ea4-4305-a7ae-c569169936c0<br>
> >>><br>
> >>> Date: Fri, 23 Jan 2015 10:43:33 GMT<br>
> >>><br>
> >>><br>
> >>> {"badRequest": {"message": "Security group bar not found for project<br>
> >>> 790f5693e97a40d38c4d5bfdc45acb09.", "code": 400}}<br>
> >>><br>
> >>><br>
> >>> and<br>
> >>><br>
> >>><br>
> >>> request:<br>
> >>><br>
> >>> POST /v2/790f5693e97a40d38c4d5bfdc45acb09/servers HTTP/1.1<br>
> >>><br>
> >>> Host: <a href="http://192.168.122.195:8774" target="_blank">192.168.122.195:8774</a><br>
> >>><br>
> >>> X-Auth-Project-Id: demo<br>
> >>><br>
> >>> Accept-Encoding: gzip, deflate, compress<br>
> >>><br>
> >>> Content-Length: 192<br>
> >>><br>
> >>> Accept: application/json<br>
> >>><br>
> >>> User-Agent: python-novaclient<br>
> >>><br>
> >>> X-Auth-Token: 24c0d30ff76c42e0ae160fa93db8cf71<br>
> >>><br>
> >>> Content-Type: application/json<br>
> >>><br>
> >>><br>
> >>> {"server": {"name": "demo", "imageRef":<br>
> >>> "171c9d7d-3912-4547-b2a5-ea157eb08622", "key_name": "foo", "flavorRef":<br>
> >>> "42", "max_count": 1, "min_count": 1, "security_groups": [{"name":<br>
> >>> "default"}]}}<br>
> >>><br>
> >>> response:<br>
> >>><br>
> >>> HTTP/1.1 400 Bad Request<br>
> >>><br>
> >>> Content-Length: 70<br>
> >>><br>
> >>> Content-Type: application/json; charset=UTF-8<br>
> >>><br>
> >>> X-Compute-Request-Id: req-87604089-7071-40a7-a34b-7bc56d0551f5<br>
> >>><br>
> >>> Date: Fri, 23 Jan 2015 10:39:43 GMT<br>
> >>><br>
> >>><br>
> >>> {"badRequest": {"message": "Invalid key_name provided.", "code": 400}}<br>
> >>><br>
> >>><br>
> >>> The former specifies an incorrect security group name, and the latter an<br>
> >>> incorrect keypair name. And the problem is, that just looking at the<br>
> >>> response body and HTTP response code an external system can’t understand<br>
> >>> what exactly went wrong. And parsing of error messages here is not the way<br>
> >>> we’d like to solve this problem.<br>
> >><br>
> >><br>
> >> For the Compute API v 2 we have the shortened Error Code in the<br>
> >> documentation at<br>
> >> <a href="http://developer.openstack.org/api-ref-compute-v2.html#compute_server-addresses" target="_blank">http://developer.openstack.org/api-ref-compute-v2.html#compute_server-addresses</a><br>
> >><br>
> >> such as:<br>
> >><br>
> >> Error response codes<br>
> >> computeFault (400, 500, …), serviceUnavailable (503), badRequest (400),<br>
> >> unauthorized (401), forbidden (403), badMethod (405), overLimit (413),<br>
> >> itemNotFound (404), buildInProgress (409)<br>
> >><br>
> >> Thanks to a recent update (well, last fall) to our build tool for docs.<br>
> >><br>
> >> What we don't have is a table in the docs saying "computeFault has this<br>
> >> longer Description" -- is that what you are asking for, for all OpenStack<br>
> >> APIs?<br>
> >><br>
> >> Tell me more.<br>
> >><br>
> >> Anne<br>
> >><br>
> >><br>
> >>><br>
> >>><br>
> >>> Another example for solving this problem is AWS EC2 exception codes [1]<br>
> >>><br>
> >>><br>
> >>> So if we have some service based on Openstack projects it would be useful<br>
> >>> to have some concrete error codes(textual or numeric), which could allow to<br>
> >>> define what actually goes wrong and later correctly process obtained<br>
> >>> exception. These codes should be predefined for each exception, have<br>
> >>> documented structure and allow to parse exception correctly in each step of<br>
> >>> exception handling.<br>
> >>><br>
> >>><br>
> >>> So I’d like to discuss implementing such codes and its usage in openstack<br>
> >>> projects.<br>
> >>><br>
> >>><br>
> >>> [1] -<br>
> >>> <a href="http://docs.aws.amazon.com/AWSEC2/latest/APIReference/errors-overview.html" target="_blank">http://docs.aws.amazon.com/AWSEC2/latest/APIReference/errors-overview.html</a><br>
> >>><br>
> >>> __________________________________________________________________________<br>
> >>> OpenStack Development Mailing List (not for usage questions)<br>
> >>> Unsubscribe: <a href="http://OpenStack-dev-request@lists.openstack.org?subject:unsubscribe" target="_blank">OpenStack-dev-request@lists.openstack.org?subject:unsubscribe</a><br>
> >>> <a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" target="_blank">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br>
> >>><br>
> >><br>
> >><br>
> >><br>
> >> --<br>
> >> Anne Gentle<br>
> >> <a href="mailto:annegentle@justwriteclick.com">annegentle@justwriteclick.com</a><br>
> >><br>
> >> __________________________________________________________________________<br>
> >> OpenStack Development Mailing List (not for usage questions)<br>
> >> Unsubscribe: <a href="http://OpenStack-dev-request@lists.openstack.org?subject:unsubscribe" target="_blank">OpenStack-dev-request@lists.openstack.org?subject:unsubscribe</a><br>
> >> <a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" target="_blank">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br>
> >><br>
> ><br>
> > __________________________________________________________________________<br>
> > OpenStack Development Mailing List (not for usage questions)<br>
> > Unsubscribe: <a href="http://OpenStack-dev-request@lists.openstack.org?subject:unsubscribe" target="_blank">OpenStack-dev-request@lists.openstack.org?subject:unsubscribe</a><br>
> > <a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" target="_blank">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br>
> ><br>
><br>
><br>
> --<br>
> Sean Dague<br>
> <a href="http://dague.net" target="_blank">http://dague.net</a><br>
><br>
><br>
> __________________________________________________________________________<br>
> OpenStack Development Mailing List (not for usage questions)<br>
> Unsubscribe: <a href="http://OpenStack-dev-request@lists.openstack.org?subject:unsubscribe" target="_blank">OpenStack-dev-request@lists.openstack.org?subject:unsubscribe</a><br>
> <a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" target="_blank">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br>
><br>
><br>
> When I developed a REST API, I used a simple error document format:<br>
><br>
> { "text" : "error text", "operation" : "operation name", "id" : "error ID", "data" : { "data ID" : "data value", ... } }<br>
><br>
> which would differentiate the errors given the same HTTP response codes. The docs for each operation say what the error IDs are.<br>
><br>
> This worked well for me. I'd like to see the OS APIs pick up something like this. Problem is we'd need to bump the API version.<br>
><br>
> - Brant<br>
><br>
><br>
> __________________________________________________________________________<br>
> OpenStack Development Mailing List (not for usage questions)<br>
> Unsubscribe: <a href="http://OpenStack-dev-request@lists.openstack.org?subject:unsubscribe" target="_blank">OpenStack-dev-request@lists.openstack.org?subject:unsubscribe</a><br>
> <a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" target="_blank">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br>
<br>
</div></div><br>__________________________________________________________________________<br>
OpenStack Development Mailing List (not for usage questions)<br>
Unsubscribe: <a href="http://OpenStack-dev-request@lists.openstack.org?subject:unsubscribe" target="_blank">OpenStack-dev-request@lists.openstack.org?subject:unsubscribe</a><br>
<a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" target="_blank">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br>
<br></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature"><div>Kevin Benton</div></div>
</div></div>