<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Jan 29, 2015 at 11:41 AM, Sean Dague <span dir="ltr"><<a href="mailto:sean@dague.net" target="_blank">sean@dague.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">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>
<div class=""><div class="h5"><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>
</div></div><span class=""><font color="#888888">--<br>
Sean Dague<br>
<a href="http://dague.net" target="_blank">http://dague.net</a><br>
<br>
</font></span><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></div><div class="gmail_extra">When I developed a REST API, I used a simple error document format:<br><br>{
  "text" : "<em>error text</em>",
  "operation" : "<em>operation name</em>",
  "id" : "<em>error ID</em>",
  "data" : { "<em>data ID</em>" : "<em>data value</em>", ... }
}<br><br></div><div class="gmail_extra">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></div><div class="gmail_extra">- Brant<br></div><div class="gmail_extra"><br></div><div class="gmail_extra"><br></div></div>