Skip to content
TORNLIFE More

Include the error code as a custom HTTP header

Started by Max_Cohen [512123] on in API Development.

16 replies · 255 views · thread synced · 7 days ago · View on torn.com
About this thread

Posts archived: 17 / 17 posts (100%) · the total is Torn's reply count + the opening post at the last fetch

Counted by TornLife from the archived posts.

Archived posts
17
Discussion span
→
People posting
7
Likes on archived posts
12
Authority score
67 / 100
Historical score
25 / 100
Story score
36 / 100
Engagement score
60 / 100
Max_Cohen [512123]
It would be really convenient if I could determine if the API has returned an error object in the JSON without actually inspecting the JSON itself. My idea is simply to include the error code (1,2,3, etc) as a custom HTTP header when an error object is returned but other methods would likely be fine as well. It just simplifies the JSON deserialization if I know ahead of time what kind of object I've got.
LouBaker [1162207]
the API already returns the Errors

simple as this example: {"error":{"code":4,"error":"Wrong fields"}}

the list below is from here https://www.torn.com/api.html



0 => 'Unknown error' : Unhandled error, should not occur.
1 => 'Key is empty' : Private key is empty in current request.
2 => 'Incorrect Key' : Private key is wrong/incorrect format.
3 => 'Wrong type' : Requesting an incorrect basic type.
4 => 'Wrong fields' : Requesting incorrect selection fields.
5 => 'Too many requests' : Current private key is banned for a small period of time because of too many requests (max 100 per minute).
6 => 'Incorrect ID' : Wrong ID value.
7 => 'Incorrect ID-entity relation' : A requested selection is private (For example, personal data of another user / faction).
8 => 'IP block' : Current IP is banned for a small period of time because of abuse.
9 => 'API disabled' : Api system is currently disabled.
10 => 'Key owner is in federal jail' : Current key can't be used because owner is in federal jail.
11 => 'Key change error: You can only change your API key once every 60 seconds'.
12 => 'Key read error: Error reading key from Database'.


Note: the most common error returned is Error 9 = 'API disabled'
Max_Cohen [512123]
Yeah, I know but that is the JSON data in the response and there isn't any other indication that an error has been returned. The only way to determine if an error has been returned is to parse the JSON data. This complicates deserialization because the streams are all forward only. Without knowing the type of object I'm trying to deserialize the process goes like:
  • Check response status.
  • Read first node of JSON and determine if it is an error object.
  • If an error object then read the two properties.
  • If not an error then rewrite the json data to another stream to avoid loading all of the data into memory. (I'm unsure if this even really works or if it instantiates it all into memory and then streams it out from there again...)
  • Send new stream to deserializer to instantiate the requested type.
If I knew ahead of time it was an error I could skip doing any manual parsing of the JSON and directly deserialize the objects that I know are there. Simple as:
  • Check response status.
  • If error header present then deserialize JSON as an ApiErrorResponse object.
  • If not present then deserialize JSON as the requested type.
Alternatively I could trap an exception if the requested type fails to deserialize correctly and assume it is an error object in that case but that won't always be true and I'd like to avoid controlling program flow with exceptions. It would be much cleaner if I could know ahead of time if I have the object I expect or an error.
Stiny [992186]
What I do while deserializing is include an "error" object as an optional field in all my deserialization objects and checking that first before proceeding. If it deserialized to null then there was no error.
JotDe [2200962]
No need for custom HTTP Headers.
HTTP Status Code is the thing they should use.

HTTP 500 => 0 => 'Unknown error' : Unhandled error, should not occur.
HTTP 400 => 1 => 'Key is empty' : Private key is empty in current request.
HTTP 400 => 2 => 'Incorrect Key' : Private key is wrong/incorrect format.
HTTP 400 => 3 => 'Wrong type' : Requesting an incorrect basic type.
HTTP 400 => 4 => 'Wrong fields' : Requesting incorrect selection fields.
HTTP 429 => 5 => 'Too many requests' : Current private key is banned for a small period of time because of too many requests (max 100 per minute).
HTTP 400 => 6 => 'Incorrect ID' : Wrong ID value.
HTTP 403 => 7 => 'Incorrect ID-entity relation' : A requested selection is private (For example, personal data of another user / faction).
HTTP 403 => 8 => 'IP block' : Current IP is banned for a small period of time because of abuse.
HTTP 503 =>9 => 'API disabled' : Api system is currently disabled.
HTTP 403 => 10 => 'Key owner is in federal jail' : Current key can't be used because owner is in federal jail.
HTTP 403 => 11 => 'Key change error: You can only change your API key once every 60 seconds'.
HTTP 500 => 12 => 'Key read error: Error reading key from Database'.
Max_Cohen [512123]
Eh, I'm not so sure about this. Technically the HTTP request was successful and some data was returned. I would say those error codes are for the HTTP server to return in various scenarios. In those cases I wouldn't even try to parse the response message as data since it could very well be an error page returned by the server or some intermediate (like cloudflare). But I mostly consume web services not write them so I don't have a lot of professional experience in this area.
Milkbeard [2166458]
How is deserializing json inconvenient? Every modern language has a library that makes this trivial. I'm not sure piggybacking on HTTP status codes is the best idea in the long run.
Max_Cohen [512123]
maybe read the whole thread?

i'm using my language's JSON parsing classes. i don't think using the HTTP status is the correct way to go either.

dynamically deserializing json to determine type isn't trivial and getting type info from the data itself is prone to errors.

though, since it seems unlikely this will get added, I will just use Stiny's suggestion of including the error object as a property of the base return type.
Milkbeard [2166458]
I did read the whole thread. No need to get snippy.

I guess we have different definitions of trivial. Using a parsing language to turn json into a associative data structure to determine type doesn't seem all that complicated to me, and assuming the json is well formed (if it isn't there are bigger problems). I'm not sure how this is error prone.
JotDe [2200962]
You must distinguish between human users and machines.
Humans can do little with technical errors that are incomprehensible to them.
That is why there are usually only 2xx or 3xx status codes.

For an API that is developed for machines, the HTTP status code is just the right thing.
Because the HTTP Status Code is internationally standardized and machines love structured and standardized data. In addition, the semantics of the status codes are already described.
This reduces the effort for Torn developers, because everything has already been described by the IETF. They would only have to use it.
See https://tools.ietf.org/html/rfc7231#section-6.1
Helcostr [1934501] Wiki Editor
I am all for having status codes. Saves having to interpret surface "ok status" at both the status code lvl (for cloudflair) and the api lvl.
Helcostr [1934501] Wiki Editor
There are actually 2xx, 3xx, 4xx, and the dreaded 5xx (and occasionally 1xx).

I see a lot of these calls. You can't keep status codes away from me :3

I swear I'm human.
JotDe [2200962]
I can only say that it is not good practice to return a 404 status code to a human. Not everyone deals extensively with the things you should do and things you can do. Look at the big frameworks. Usually the undefined errors are caught by middleware and converted to an HTTP 200.
Helcostr [1934501] Wiki Editor
probably watching coding websites return status codes like github star wars themed parallaxing 404 is what got me to memorize error codes. And besides, an error code helps figure out what the issue is... instead of a f**king message box that keeps popping up saying "technical issues" argggg (humans cant read status codes, but i notice if someone does a 301 redirect on me, 404 is just way too classic, and 500 is funny)
Max_Cohen [512123]
Because attempting to deserialize JSON to a type that it isn't will throw an exception unless I specifically read ahead and determine the type myself. How do I know I'm right about the type? I don't really, it's mostly a guess from inference. All of this is more wishy-washy than I usually like. Yeah, it will work. Could it be better? Yes. Either way calling it trivial just because the language you use is more forgiving of type errors is overlooking the broader picture.

I don't want to deserialize twice. I don't want to copy data from an array to an object (especially considering some API responses won't fit nicely into an array since they have complex types as properties). I don't want to just treat everything as System.Object because that's awful. I just want to be sure what type I should be deserializing the response to and not have to guess about it and double check it in my code.