7

Our company runs applications on a Micro Service architecture that includes thousands of services. I am working on a backend application "X" that talks to 50+ services. Frontend services call my service "X" to execute requests on other services.

Problem:

Front end wants to show user friendly messages when something fails on other services.

  1. Other services do not return user friendly messages. It is not possible for me to request changes by other teams as there are several.
  2. There are no agreed error codes as such. Other services return a string error message. Currently, it is passed back to the UI. Sometimes the error messages are a pointer references (bad code :/)

Possible Solution:

Check for error message string and have a mapping in my service to a user friendly message. But things can break if the callee service changed their error message. Fallback to a default error message when a custom error mapping is not found.

Any more ideas on scalable and sustainable solution? Thanks!

  • How do you know whether the other services failed or not? Just by the response message? Do they respond with any useful http status? 5xx, 4xx? Or do they all end in 200? – Laiv Jan 16 '18 at 19:38
  • Its not HTTP. Its a different protocol that returns an error. There is a service definition. If there is no error, then the response is checked for service defined response format. – TechCrunch Jan 16 '18 at 19:49
  • Could be useful to know what protocol is. Is it any well-known? Amqp? SMTP? Ws? Protobuf? – Laiv Jan 16 '18 at 20:34
  • 3
    Get the other teams to return meaningful error messages or consistent and meaningful error codes? Things can always break if the other team changes their API unexpectedly, so they need to not do that – immibis Jan 17 '18 at 1:06
  • It is TChannel and uses Thrift for specification – TechCrunch Jan 17 '18 at 2:02
3

Disclaimers

Our company runs applications on a Micro Service architecture that includes thousands of services. I am working on a backend application "X" that talks to 50+ services. Frontend services call my service "X" to execute requests on other services.

First of all, thousands of random services don't make an architecture to be Microservices like architecture. It's still necessary a certain sense of a "whole" and a little bit of arrangement among services. Guidelines or rules of thumb.

Contextualize the backend within the 'whole'

I assume, your backend is neither gateway nor proxy. I guess it has its own business and a well defined bounded context. So, regarding other services, the backend is a facade.

As a facade, hiding implementation details (as for instance, integrations with remote services) is among its responsibilities. For the front-end (and hence, the end-user), the only trustful interlocutor is X and no implementation detail should reach outer layers. Whatever happened under the hood, it's not user's business.

That doesn't mean we can not tell to the user that something went wrong. We can, but we do it abstracting these details. We won't give the sense of something remote is failing. Right the opposite, something in X failed and that's it.

Since we are speaking about thousands of possible integrations (+50 atm), the number of possible and different errors is significant. If we map every single one to a custom message, the end-user is going to be overwhelmed by so many (and uncontextualized) information. If we map all the errors to a small set of custom errors, we are biasing the information, making hard for us to track the problem and solve it.

In my opinion, error messages should provide to the user with the sense that there's something we can do to amend the problem.

Nevertheless, if end-users still want to know what's going on under the hood, there are other ways more useful for the entire organization.

Accountability

  1. Other services do not return user-friendly messages. It is not possible for me to request changes by other teams as there are several.There are no agreed error codes as such.

  2. Other services return a string error message. Currently, it is passed back to the UI. Sometimes the error messages are a pointer references (bad code :/)

As developer, your responsibility is to expose these arguments to the stakeholders. It's a matter of accountability. In my opinion, there's a leak of technical leadership and that's a real problem when it comes to distributed systems.

There's no technical envision. If there was, services would be implemented upon rules of thumb addressed to make the system scalable and ease the integrations among services. Right now looks like services appear wildly, without the sense of contribution to the "whole".

If I were asked to do what you have been requested to do (and I have been sometimes), I would argue whether turning the current anarchy into user-friendly messages is beyond the scope of X.

At least, "rise the hand", expose your concerns, expose your alternatives and let whoever has the accountability to decide.

Make your solutions valuable for the company

Check for error message string and have a mapping in my service to a user-friendly message. But things can break if the callee service changed their error message. Fallback to a default error message when a custom error mapping is not found.

You are right. That's a weak solution. It's brittle and inefficient in the mid-long run.

I also think it causes coupling since changes in these strings might force you to refractor the mappings. Not a big deal improvement.

Any more ideas on a scalable and sustainable solution?

Reporting. Handle the errors, give a code/ticket/id to them and report. Then, allow the front-end to visualize the report. For instance, sharing a link to the reporting service.

Error. < A user-friendly and very default error message >. Follow the link for further information

This way, you can integrate as many services as you need. And you release yourself from the overhead of handling and translating random strings into new random, but user-friendly, strings.

The reporting service is reusable for the rest of the services so that, if you have correlated IDs, should be possible for you to allow users to have a panoramic view of the errors and the causes. In distributed architectures, traceability is quite important.

Later, the reporting service can be enhanced with as many mappings as you need to give readable and useful instructions about what to do if error X happens. If strings change here doesn't matters at all. What we have (store) is a final state of the report.

The reporting service will open the door to a possible normalization of the errors within the organization since the service will expose a public API (hence a contract).

0

There is no miracle in your case. The possible solution seems the solution that you already proposed.

Check for error message string and have a mapping in my service to a user friendly message. But things can break if the callee service changed their error message. Fallback to a default error message when a custom error mapping is not found.

It's ok to a API change the error message if the API return some kind of error code too, which the API consumer can use to track the error and map for another message (like you trying to do, but with the message).

Only make sure to log the message that the API returned before execute the fallback error. Maybe you can add the API message in some kind of developerMessage in your custom error, helping to identify the problem without use the log (only make sure that their API not throws any message with sensible information).

If you have some communication channel with the team that are doing this services, explain your problem and ask for some help from them, because that could be the same problem for the another team that are trying to use their API.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.