Re: [openstack-dev] [api] Changing 403 Forbidden to 400 Bad Request for OverQuota was: [nova] Which error code should we return when OverQuota

2015-05-06 Thread Everett Toews
On May 6, 2015, at 1:58 PM, David Kranz 
dkr...@redhat.commailto:dkr...@redhat.com wrote:

+1
The basic problem is we are trying to fit a square (generic api) peg in a round 
(HTTP request/response) hole.
But if we do say we are recognizing sub-error-codes, it might be good to 
actually give them numbers somewhere in the response (maybe an error code 
header) rather than relying on string matching to determine the real error. 
String matching is fragile and has icky i18n implications.

There is an effort underway around defining such sub-error-codes” [1]. Those 
error codes would be surfaced in the REST API here [2]. Naturally feedback is 
welcome.

Everett


[1] https://review.openstack.org/#/c/167793/
[2] https://review.openstack.org/#/c/167793/
__
OpenStack Development Mailing List (not for usage questions)
Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe
http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev


Re: [openstack-dev] [api] Changing 403 Forbidden to 400 Bad Request for OverQuota was: [nova] Which error code should we return when OverQuota

2015-05-06 Thread Ryan Brown
On 05/06/2015 02:07 PM, Jay Pipes wrote:
 Adding [api] topic. API WG members, please do comment.
 
 On 05/06/2015 08:01 AM, Sean Dague wrote:
 On 05/06/2015 07:11 AM, Chris Dent wrote:
 On Wed, 6 May 2015, Sean Dague wrote:

 All other client errors, just be a 400. And use the emerging error
 reporting json to actually tell the client what's going on.

 Please do not do this. Please use the 4xx codes as best as you
 possibly can. Yes, they don't always match, but there are several of
 them for reasons™ and it is usually possible to find one that sort
 of fits.

I agree with Jay here: there are only 100 error codes in the 400
namespace, and (way) more than 100 possible errors. The general 400 is
perfectly good as a catch-all where the user can be expected to read the
JSON error response for more information, and the other error codes
should be used to make it easier for folks to distinguish specific
conditions.

Let's take the 403 case. If you are denied with your credentials,
there's no error handling that you're going to be able to fix that.

 Using just 400 is bad for a healthy HTTP ecosystem. Sure, for the
 most part people are talking to OpenStack through official clients
 but a) what happens when they aren't, b) is that the kind of world
 we want?

 I certainly don't. I want a world where the HTTP APIs that OpenStack
 and other services present actually use HTTP and allow a diversity
 of clients (machine and human).

Wanting other clients to be able to plug right in is why we try to be
RESTful and make error codes that are usable by any client (see the
error codes and messages specs). Using Conflict and Forbidden codes
in addition to good error messages will help, if they denote very
specific conditions that the user can act on.

 Absolutely. And the problem is there is not enough namespace in the HTTP
 error codes to accurately reflect the error conditions we hit. So the
 current model means the following:

 If you get any error code, it means multiple failure conditions. Throw
 it away, grep the return string to decide if you can recover.

 My proposal is to be *extremely* specific for the use of anything
 besides 400, so there is only 1 situation that causes that to arise. So
 403 means a thing, only one thing, ever. Not 2 kinds of things that you
 need to then figure out what you need to do.

Agreed

 If you get a 400, well, that's multiple kinds of errors, and you need to
 then go conditional.

 This should provide a better experience for all clients, human and
 machine.
 
 I agree with Sean on this one.
 
 Using response codes effectively makes it easier to write client code
 that is either simple or is able to use generic libraries effectively.

 Let's be honest: OpenStack doesn't have a great record of using HTTP
 effectively or correctly. Let's not make it worse.

 In the case of quota, 403 is fairly reasonable because you are in
 fact Forbidden from doing the thing you want to do. Yes, with the
 passage of time you may very well not be forbidden so the semantics
 are not strictly matching but it is more immediately expressive yet
 not quite as troubling as 409 (which has a more specific meaning).

 Except it's not, because you are saying to use 403 for 2 issues (Don't
 have permissions and Out of quota).

 Turns out, we have APIs for adjusting quotas, which your user might have
 access to. So part of 403 space is something you might be able to code
 yourself around, and part isn't. Which means you should always ignore it
 and write custom logic client side.

 Using something beyond 400 is *not* more expressive if it has more than
 one possible meaning. Then it's just muddy. My point is that all errors
 besides 400 should have *exactly* one cause, so they are specific.
 
 Yes, agreed.
 
 I think Sean makes an excellent point that if you have 1 condition that
 results in a 403 Forbidden, it actually does not make things more
 expressive. It actually just means both humans and clients need to now
 delve deeper into the error context to determine if this is something
 they actually don't have permission to do, or whether they've exceeded
 their quota but otherwise have permission to do some action.
 
 Best,
 -jay
 
 p.s. And, yes, Chris, I definitely do see your side of the coin on this.
 It's nuanced, and a grey area...
 
 __
 OpenStack Development Mailing List (not for usage questions)
 Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe
 http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev

-- 
Ryan Brown / Software Engineer, Openstack / Red Hat, Inc.

__
OpenStack Development Mailing List (not for usage questions)
Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe
http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev


Re: [openstack-dev] [api] Changing 403 Forbidden to 400 Bad Request for OverQuota was: [nova] Which error code should we return when OverQuota

2015-05-06 Thread David Kranz

On 05/06/2015 02:07 PM, Jay Pipes wrote:

Adding [api] topic. API WG members, please do comment.

On 05/06/2015 08:01 AM, Sean Dague wrote:

On 05/06/2015 07:11 AM, Chris Dent wrote:

On Wed, 6 May 2015, Sean Dague wrote:


All other client errors, just be a 400. And use the emerging error
reporting json to actually tell the client what's going on.


Please do not do this. Please use the 4xx codes as best as you
possibly can. Yes, they don't always match, but there are several of
them for reasons™ and it is usually possible to find one that sort
of fits.

Using just 400 is bad for a healthy HTTP ecosystem. Sure, for the
most part people are talking to OpenStack through official clients
but a) what happens when they aren't, b) is that the kind of world
we want?

I certainly don't. I want a world where the HTTP APIs that OpenStack
and other services present actually use HTTP and allow a diversity
of clients (machine and human).


Absolutely. And the problem is there is not enough namespace in the HTTP
error codes to accurately reflect the error conditions we hit. So the
current model means the following:

If you get any error code, it means multiple failure conditions. Throw
it away, grep the return string to decide if you can recover.

My proposal is to be *extremely* specific for the use of anything
besides 400, so there is only 1 situation that causes that to arise. So
403 means a thing, only one thing, ever. Not 2 kinds of things that you
need to then figure out what you need to do.

If you get a 400, well, that's multiple kinds of errors, and you need to
then go conditional.

This should provide a better experience for all clients, human and 
machine.


I agree with Sean on this one.


Using response codes effectively makes it easier to write client code
that is either simple or is able to use generic libraries effectively.

Let's be honest: OpenStack doesn't have a great record of using HTTP
effectively or correctly. Let's not make it worse.

In the case of quota, 403 is fairly reasonable because you are in
fact Forbidden from doing the thing you want to do. Yes, with the
passage of time you may very well not be forbidden so the semantics
are not strictly matching but it is more immediately expressive yet
not quite as troubling as 409 (which has a more specific meaning).


Except it's not, because you are saying to use 403 for 2 issues (Don't
have permissions and Out of quota).

Turns out, we have APIs for adjusting quotas, which your user might have
access to. So part of 403 space is something you might be able to code
yourself around, and part isn't. Which means you should always ignore it
and write custom logic client side.

Using something beyond 400 is *not* more expressive if it has more than
one possible meaning. Then it's just muddy. My point is that all errors
besides 400 should have *exactly* one cause, so they are specific.


Yes, agreed.

I think Sean makes an excellent point that if you have 1 condition 
that results in a 403 Forbidden, it actually does not make things more 
expressive. It actually just means both humans and clients need to now 
delve deeper into the error context to determine if this is something 
they actually don't have permission to do, or whether they've exceeded 
their quota but otherwise have permission to do some action.


Best,
-jay

+1
The basic problem is we are trying to fit a square (generic api) peg in 
a round (HTTP request/response) hole.
But if we do say we are recognizing sub-error-codes, it might be good 
to actually give them numbers somewhere in the response (maybe an error 
code header) rather than relying on string matching to determine the 
real error. String matching is fragile and has icky i18n implications.


 -David


p.s. And, yes, Chris, I definitely do see your side of the coin on 
this. It's nuanced, and a grey area...


__ 


OpenStack Development Mailing List (not for usage questions)
Unsubscribe: 
openstack-dev-requ...@lists.openstack.org?subject:unsubscribe

http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev



__
OpenStack Development Mailing List (not for usage questions)
Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe
http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev


Re: [openstack-dev] [api] Changing 403 Forbidden to 400 Bad Request for OverQuota was: [nova] Which error code should we return when OverQuota

2015-05-06 Thread Chris Dent

On Wed, 6 May 2015, Jay Pipes wrote:

I think Sean makes an excellent point that if you have 1 condition that 
results in a 403 Forbidden, it actually does not make things more expressive. 
It actually just means both humans and clients need to now delve deeper into 
the error context to determine if this is something they actually don't have 
permission to do, or whether they've exceeded their quota but otherwise have 
permission to do some action.


As I said to Sean in IRC, I can see where you guys are coming from
and I haven't really got a better counter-proposal than my experience
writing servers and clients doesn't like this so it's not like I want
to fight about it. I do think it is worth discussion and there are
obviously costs either way that we should identify and balance.
Interestingly, in the process of writing this response I think I've
managed to come up with a few reasons. On the other hand maybe I'm
just getting out yet more paint for the shed.

Basically it seems to me that the proposal to use 400 just moves the
problem around, one option has conditionals localized under 400,
centralizing the ambiguity. The other option puts the ambiguity in
categories. I guess my brain works better with the latter: a kind of
cascading decision tree.

Note: I think we're all perpetuating the myth or wish that we actually
do do something in code in response to 400 errors. Maybe in some very
special clients it might happen, but in ad-hoc clients (the best kind)
for the most part we report the status and fail and let the human decide
what's next.

In that sort of context I want the response _codes_ to have some
semantics because I want to branch on the codes (if I branch at all)
and nothing else:

* 400: bro, something bogus happened, I'm pretty sure it was your
   fault
* 401: Tell me who you are and you might get to do this
* 402: You might get to do this if you pay
* 403: You didn't get to do this because the _server_ forbids you
* 404: You didn't get to do this because it ain't there
* 405: You didn't get to do this because that action is not available
* 406: I've got the thing you want, but not in the form you want it
* 407: Some man in the middle proxy needs auth
* 408: You spoke too slowly for my awesome brains
* 409: Somebody else got there first
* 410: Seriously, it ain't there and it never will be
* 411: Why u no content-length!?
* 412: You sent conditional headers and I can't meet their
   requirements
* 413: Too big in the body!
* 414: Too big in the URI!
* 415: You sent me a thing and I might have been able to do
   something with it if it were in a different form
[...]

These all mean things as defined by rfcs 7231 and 7235. Those rfcs
were not pulled out of thin air: They are part of the suite of rfcs
that define HTTP. Do we want to do HTTP? Yes, I think so. In that case,
we ought to follow it where possible.

Each of those codes above have different levels of ambiguity. Some
are quite specific. For example 405, 406, 411, 412 and 415. Where we
can be sure they are the correct response we should use them and
most assuredly _not_ 400.

403, as you've both identified, is a lot more squiffy: the server
understood the request but refuses to authorize it...a request
might be forbidden for reasons unrelated to the credentials.

Which leads us to 400. How I tend to use 400 is when none of 405, 406,
409, 411, 412 or 415 can be used because the representation is
_claiming_ legitimate form (based on the headers) and no conditionals
are being violated and where none of 401, 403 or 404 can be used because
the thing is there, I am authentic and the server is not forbidding .
What that means is that there's some crufty about the otherwise good
representation: You've claimed to be sending JSON and you did, but you
left out a required field.

There is no other 4xx that covers that, thus 400.

Now if we try to meld my rules with this idea about signifying over
quota, I feel we've now discovered some collisions:

My use of 400 means there's something wrong with your request.
This is also what the spec says: the client seems to have erred.

Both of these essentially say that request was pretty okay, but not
quite right and you can change the _request_ (or perhaps the client
side environment) and achieve success.

In the case of quota you need to change the server side environment,
not this request. In fact if you do change the server (your quota)
and then do the same request again it will likely work.

Looking at 403 again: the server understood the request but refuses
to authorize it.

4xx means client side error (The 4xx (Client Error) class of status
code indicates that the client seems to have erred.), so arguably
over quota doesn't really work in _any_ 4xx because the client made no
error, the service just has a quota lower than they need. We don't
want to go down the non 4xx road at this time, so given our choices
403 is the one that most says the server 

Re: [openstack-dev] [api] Changing 403 Forbidden to 400 Bad Request for OverQuota was: [nova] Which error code should we return when OverQuota

2015-05-06 Thread Ryan Brown
On 05/06/2015 03:15 PM, Chris Dent wrote:
 On Wed, 6 May 2015, Jay Pipes wrote:
 
 I think Sean makes an excellent point that if you have 1 condition
 that results in a 403 Forbidden, it actually does not make things more
 expressive. It actually just means both humans and clients need to now
 delve deeper into the error context to determine if this is something
 they actually don't have permission to do, or whether they've exceeded
 their quota but otherwise have permission to do some action.
 
 As I said to Sean in IRC, I can see where you guys are coming from
 and I haven't really got a better counter-proposal than my experience
 writing servers and clients doesn't like this so it's not like I want
 to fight about it. I do think it is worth discussion and there are
 obviously costs either way that we should identify and balance.
 Interestingly, in the process of writing this response I think I've
 managed to come up with a few reasons. On the other hand maybe I'm
 just getting out yet more paint for the shed.
 
 Basically it seems to me that the proposal to use 400 just moves the
 problem around, one option has conditionals localized under 400,
 centralizing the ambiguity. The other option puts the ambiguity in
 categories. I guess my brain works better with the latter: a kind of
 cascading decision tree.
 
 Note: I think we're all perpetuating the myth or wish that we actually
 do do something in code in response to 400 errors. Maybe in some very
 special clients it might happen, but in ad-hoc clients (the best kind)
 for the most part we report the status and fail and let the human decide
 what's next.

Guilty as charged. It may be that the benefit of moving 403-400 isn't
worth the trouble in any case (though I'd prefer it) since there are
already clients out in the world that may/may not rely on this behavior.

 In that sort of context I want the response _codes_ to have some
 semantics because I want to branch on the codes (if I branch at all)
 and nothing else:
 
 * 400: bro, something bogus happened, I'm pretty sure it was your
fault
 * 401: Tell me who you are and you might get to do this
 * 402: You might get to do this if you pay
 * 403: You didn't get to do this because the _server_ forbids you
 * 404: You didn't get to do this because it ain't there
 * 405: You didn't get to do this because that action is not available
 * 406: I've got the thing you want, but not in the form you want it
 * 407: Some man in the middle proxy needs auth
 * 408: You spoke too slowly for my awesome brains
 * 409: Somebody else got there first
 * 410: Seriously, it ain't there and it never will be
 * 411: Why u no content-length!?
 * 412: You sent conditional headers and I can't meet their
requirements
 * 413: Too big in the body!
 * 414: Too big in the URI!
 * 415: You sent me a thing and I might have been able to do
something with it if it were in a different form
 [...]
 
 These all mean things as defined by rfcs 7231 and 7235. Those rfcs
 were not pulled out of thin air: They are part of the suite of rfcs
 that define HTTP. Do we want to do HTTP? Yes, I think so. In that case,
 we ought to follow it where possible.
 
 Each of those codes above have different levels of ambiguity. Some
 are quite specific. For example 405, 406, 411, 412 and 415. Where we
 can be sure they are the correct response we should use them and
 most assuredly _not_ 400.
 
 403, as you've both identified, is a lot more squiffy: the server
 understood the request but refuses to authorize it...a request
 might be forbidden for reasons unrelated to the credentials.
 
 Which leads us to 400. How I tend to use 400 is when none of 405, 406,
 409, 411, 412 or 415 can be used because the representation is
 _claiming_ legitimate form (based on the headers) and no conditionals
 are being violated and where none of 401, 403 or 404 can be used because
 the thing is there, I am authentic and the server is not forbidding .
 What that means is that there's some crufty about the otherwise good
 representation: You've claimed to be sending JSON and you did, but you
 left out a required field.
 
 There is no other 4xx that covers that, thus 400.
 
 Now if we try to meld my rules with this idea about signifying over
 quota, I feel we've now discovered some collisions:
 
 My use of 400 means there's something wrong with your request.
 This is also what the spec says: the client seems to have erred.
 
 Both of these essentially say that request was pretty okay, but not
 quite right and you can change the _request_ (or perhaps the client
 side environment) and achieve success.
 
 In the case of quota you need to change the server side environment,
 not this request. In fact if you do change the server (your quota)
 and then do the same request again it will likely work.
 
 Looking at 403 again: the server understood the request but refuses
 to authorize it.
 

Very good point. I was thinking 

[openstack-dev] [api] Changing 403 Forbidden to 400 Bad Request for OverQuota was: [nova] Which error code should we return when OverQuota

2015-05-06 Thread Jay Pipes

Adding [api] topic. API WG members, please do comment.

On 05/06/2015 08:01 AM, Sean Dague wrote:

On 05/06/2015 07:11 AM, Chris Dent wrote:

On Wed, 6 May 2015, Sean Dague wrote:


All other client errors, just be a 400. And use the emerging error
reporting json to actually tell the client what's going on.


Please do not do this. Please use the 4xx codes as best as you
possibly can. Yes, they don't always match, but there are several of
them for reasons™ and it is usually possible to find one that sort
of fits.

Using just 400 is bad for a healthy HTTP ecosystem. Sure, for the
most part people are talking to OpenStack through official clients
but a) what happens when they aren't, b) is that the kind of world
we want?

I certainly don't. I want a world where the HTTP APIs that OpenStack
and other services present actually use HTTP and allow a diversity
of clients (machine and human).


Absolutely. And the problem is there is not enough namespace in the HTTP
error codes to accurately reflect the error conditions we hit. So the
current model means the following:

If you get any error code, it means multiple failure conditions. Throw
it away, grep the return string to decide if you can recover.

My proposal is to be *extremely* specific for the use of anything
besides 400, so there is only 1 situation that causes that to arise. So
403 means a thing, only one thing, ever. Not 2 kinds of things that you
need to then figure out what you need to do.

If you get a 400, well, that's multiple kinds of errors, and you need to
then go conditional.

This should provide a better experience for all clients, human and machine.


I agree with Sean on this one.


Using response codes effectively makes it easier to write client code
that is either simple or is able to use generic libraries effectively.

Let's be honest: OpenStack doesn't have a great record of using HTTP
effectively or correctly. Let's not make it worse.

In the case of quota, 403 is fairly reasonable because you are in
fact Forbidden from doing the thing you want to do. Yes, with the
passage of time you may very well not be forbidden so the semantics
are not strictly matching but it is more immediately expressive yet
not quite as troubling as 409 (which has a more specific meaning).


Except it's not, because you are saying to use 403 for 2 issues (Don't
have permissions and Out of quota).

Turns out, we have APIs for adjusting quotas, which your user might have
access to. So part of 403 space is something you might be able to code
yourself around, and part isn't. Which means you should always ignore it
and write custom logic client side.

Using something beyond 400 is *not* more expressive if it has more than
one possible meaning. Then it's just muddy. My point is that all errors
besides 400 should have *exactly* one cause, so they are specific.


Yes, agreed.

I think Sean makes an excellent point that if you have 1 condition that 
results in a 403 Forbidden, it actually does not make things more 
expressive. It actually just means both humans and clients need to now 
delve deeper into the error context to determine if this is something 
they actually don't have permission to do, or whether they've exceeded 
their quota but otherwise have permission to do some action.


Best,
-jay

p.s. And, yes, Chris, I definitely do see your side of the coin on this. 
It's nuanced, and a grey area...


__
OpenStack Development Mailing List (not for usage questions)
Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe
http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev


Re: [openstack-dev] [api] Changing 403 Forbidden to 400 Bad Request for OverQuota was: [nova] Which error code should we return when OverQuota

2015-05-06 Thread Xu, Hejie
Learn a lot again!   ++ for sub-error-codes.

From: Everett Toews [mailto:everett.to...@rackspace.com]
Sent: Thursday, May 7, 2015 6:26 AM
To: OpenStack Development Mailing List (not for usage questions)
Subject: Re: [openstack-dev] [api] Changing 403 Forbidden to 400 Bad Request 
for OverQuota was: [nova] Which error code should we return when OverQuota

On May 6, 2015, at 1:58 PM, David Kranz 
dkr...@redhat.commailto:dkr...@redhat.com wrote:


+1
The basic problem is we are trying to fit a square (generic api) peg in a round 
(HTTP request/response) hole.
But if we do say we are recognizing sub-error-codes, it might be good to 
actually give them numbers somewhere in the response (maybe an error code 
header) rather than relying on string matching to determine the real error. 
String matching is fragile and has icky i18n implications.

There is an effort underway around defining such sub-error-codes [1]. Those 
error codes would be surfaced in the REST API here [2]. Naturally feedback is 
welcome.

Everett


[1] https://review.openstack.org/#/c/167793/
[2] https://review.openstack.org/#/c/167793/
__
OpenStack Development Mailing List (not for usage questions)
Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe
http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev