Error error everywhere, which error code shall I use?

When we talk about any web service design or API Design, we definitely care about the functionality and the positive flows. It’s important for an application to cater to the business requirements. But it’s equally important for it, to behave in a close to certain and standard way, in terms of negative and erroneous situations. The error handling becomes more important when you have a wide base of consumers. Suppose an API developer named Jackson (from Hong Kong) is building an application which will be consumed by the developers of Banks across various regions. The banks may include NAB from Australia, DBS from Singapore, ICICI Bank from India, JP Morgan from the USA and so on. Now there are two major notions that come into the picture. Firstly, the error handling should be done in such a way that it is understood by each and every consumer. Secondly, Jackson is not supposed to expose the internal details of the application, because it may leave his application in a vulnerable condition. To handle the second condition, HTTP has already defined standard HTTP Status Codes for various conditions. But Jackson is confused, as he has to adhere to the second condition as well. His job was easy if he was asked to map all the Backend related error description (error code and the error message) to the application. And create as many status code entries as there are in the Backend. But it will affect the user-friendliness of the application. On the other hand, the error message will display the internal details of the application. For example, if the Database connectivity was lost, the error message from the Backend will clearly say this in the error message. Now, if Jackson exposes this error message to the actual application consumer. After using the application for a long time, the consumer knows which error is most frequent, and how to put the system down. So we definitely don’t want the external parties to know about this kind of error description. On the other hand, if Jackson is giving a bunch of error status codes including the common and the rarely used ones. It’s not only going to increase the complexity of the application but the consumers also have to dig their heads before they can smoothly use the application. The most adverse effect will be on the end user, a common man, who is not a developer but relates to the business team. It will be so hectic for them to get a cheat sheet of error codes and mugging up 413, 415, 422 and so on. So in what way Jackson should design his application? What you can think of? Proceed to the next section to find out…

To address all the situations that may increase the design complexity and might be vulnerable, we can reduce the number of the status codes and the error description that we are going to provide to the customer. Below is the list of some error codes which are not only good to have. But you can build an entire application based on just these few error codes. Trust me, you don’t need a huge number of error codes to build your application. There are various applications which are being used worldwide and are having merely 5 status codes, including the positive ones. The detailed description of the mandatory error status codes is given at the end. But few sets of “must have” error codes are given below.

Approach one (For Software Engineers who don’t want to make their lives miserable, just kidding)

  • 400 – Bad Request
  • 401 – Unauthorized
  • 500 – Server Error

Approach two (For Software Engineers who don’t want to make other’s lives miserable)

  • 400 – Bad Request
  • 401 – Unauthorized
  • 403 – Forbidden
  • 404 – Resource Not Found
  • 500 – Server Error

Approach three

  • 400 – Bad Request
  • 401 – Unauthorized
  • 403 – Forbidden
  • 404 – Resource Not Found
  • 409 – Conflict
  • 500 – Server Error
  • 504 – Gateway Timeout, when the server doesn’t receive the timely response from the upstream.

Your job can be done in the third set above, but I would like to mention two more useful and common error codes. You can club them in the second or third approach above.

  • 429 – Too Many Requests. (Optional, you can happily throw 500 in such cases)
  • 503 – Service Unavailable (Optional, again, you shouldn’t worry if you are not throwing the 503 explicitly, as the client can’t do anything but just wait to hit after some time.).

The first one is the most confined approach and contains the boss of all the mandatory error codes. It can be used for some internal, or lightweight applications, or where the simplicity is the key concern.

The second approach is what I recommend most of the developers/architects should follow for publicly exposed applications. And is being used globally for various applications. This is because the error codes present in this category are the mandatory ones, and you simply don’t need any other error code if you have these. But, you can also have a combination of error codes from the ones mentioned above and build your application.

The third approach is useful when you have complex requests and the user is mostly an application rather than a real human. Because, it is beneficial to give more specific error code in some cases, and you can’t settle down with the second approach. Jackson is glad now and is using the second approach for his application. The consumers are happily consuming his application without mugging up the status codes sheet. Having said that, I would again recommend sticking to approach two. Most importantly, these are not the hard and fast rules that have to be followed, but it’s more like a guidebook. If you are thinking to have only these error codes in your application, you should not be concerned. You can have some specific error on top of it, if it’s really required for your application like 415 – Unsupported Media type, etc. This might be required when your application is dealing with various media types. But for Jackson who just has a couple of Media Types in his application, throwing 400 will do the same job.

HTTP Status CodeBrief about the errorError Definitions as per the HTTP standard
400Bad Request – When something is missing or not allowed in the request. Header, query param, body or path.The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications.
401Unauthorized When someone passes wrong auth credentials or expired credentials. It’s unauthenticated to be precise.Status code indicates that the request has not been applied because it lacks valid authentication credentials for the target resource. The server generating a 401 response MUST send a WWW- Authenticate header field (Section 4.1) containing at least one challenge applicable to the target resource.
403Forbidden – When someone has the valid auth credentials but doesn’t have access to a particular business functionality/API resource. Unauthorized to access.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.
404Not found – When the request is unable to find the requested response (parameter/body) in the backend. For eg., querying something which is not available in the database.The server has not found anything matching the Request-URI. No indication is given of whether the condition is temporary or permanent.
500Server Error – When the server is unable to receive or process the request. Error in any component like DB, Backend, etc.The server encountered an unexpected condition which prevented it from fulfilling the request.

One thought on “Error error everywhere, which error code shall I use?

Leave a comment