External APIs are vital in a number of Odoo integrations; however, communication between two systems may not always be very fast. The API server may respond very slowly, the connection may stop functioning properly, or the external service could have gone down temporarily. In these cases Odoo experiences a timeout while waiting for a response.
The proper handling of these timeouts is vital in keeping integrations reliable. Sending requests again and again may not be safe because it may lead to sending the same request multiple times. Odoo 19 developers have a variety of tools and mechanisms at their disposal, such as request timeouts, result handling, controlled retrying, logging or correct synchronization to diminish the interrupts of integration processes.
What Does an API Timeout Mean?
An API timeout denotes that Odoo has waited too long for a response from a third-party service. Rather than procrastinating endlessly for the external service to reply, the operation will cease and raise a timeout error in Python.
There are several reasons why that would happen. The third-party server may currently go through a high load, there may be an issue with the network itself, or it may just take a little longer to complete the particular operation. Sometimes the third-party service might be temporarily unavailable.
For instance, a specific Odoo module sends a sales order to some external e-commerce platform. After the request from Odoo is sent out, the external server does not respond within the acceptable time frame. Thus, Odoo considers the request to be timed out.
Importantly, the timeout does not mean that the external system has not received the request at all. The external service can receive and process the request; however, there may be some issue somewhere along the route of the response which makes it impossible for Odoo to receive it.
Setting a Timeout for an API Request
Timeouts in Odoo integrations using the Python requests library can be set during the request.
import requests
response = requests.get(
api_url,
headers=headers,
timeout=30,
)
response.raise_for_status()
Here, it should be noted that Odoo will not wait for the external service for an indefinite amount of time. If the configured timeout expires and the request has not received the proper response, an error will rise.
It is advisable to incorporate the concept of timeout into integrations. Without a timeout value, a slow external server could cause the request to wait indefinitely, which could create a series of issues when carrying several requests at the same Odoo server.
Careful consideration should be given to choosing the timeout value. That is, some APIs require a very low timeout value, whereas some endpoints could require more time to perform complex operations.
Handling Timeout Exceptions
A timeout should generally be treated differently than other types of API errors. The requests module of Python contains a special exception for this kind of situation.
import requests
try:
response = requests.get(
api_url,
headers=headers,
timeout=30,
)
response.raise_for_status()
except requests.exceptions.Timeout:
_logger.warning(
"API request timed out for record %s",
record.name,
)
After this, the next action will depend on the integration's purpose. Odoo can, for example, either put the record aside for subsequent retransmission or indicate an appropriate status to the user or leave it for future attempts.
The important point is that the timeout is not simply lost in the sea of a common error. The logs should contain information about what happened for a future investigation.
Connection Timeout and Read Timeout
Connection timeouts can vary from one thing to another. Connection timeouts are said to happen when an application makes a timeout before a connection to an external server is accomplished successfully. A read timeout occurs once a successful connection is established, but the server has not responded in the right time.
A much-awaited feature of the Python requests library is that you can define these timeouts separately.
response = requests.get(
api_url,
headers=headers,
timeout=(10, 30),
)
In this example, Odoo gives you time to establish a connection of 10 seconds and the time to get an actual response of 30 seconds.
That makes all the difference when it comes to dealing with an external service that is reachable but takes some time for processing the request.
Is It Safe to Retry a Timed-Out Request?
At this point, we see that timeout handling is not limited to handling exceptions only. Take the case with Odoo integrating with an external system for an order. Odoo sends the request, but it takes too long for the external system to respond. The integration then sees a timeout. Here, it is important to handle retries properly because sending the same request again might result in creating another order. So the developers need to understand the request they are retrying.
It is generally less complicated to retry a request when it:
- Only retrieves some information
- Expectations from the API are that it is idempotent
- The request has a unique reference
- It can be verified by Odoo if this operation has been executed
- The external service suggests a way of checking if the record already exists.
Retrying operations like the creation of orders, invoices, payments, and shipments should be done with more caution.
Using Controlled Retries
Even if network issues occur from time to time, avoiding retries completely is not feasible. A preferable solution would be to retry a number of times with a pause in between attempts.
Here is an easy example:
import time
import requests
for attempt in range(3):
try:
response = requests.get(
api_url,
headers=headers,
timeout=30,
)
response.raise_for_status()
break
except requests.exceptions.Timeout:
_logger.warning(
"API timeout on attempt %s",
attempt + 1,
)
if attempt == 2:
raise
time.sleep(2)
In this example, three retries are done before giving up. The most sophisticated implementation would increase the delay after each failure. This is called exponential backoff.
Retrials should also be limited to the errors which can be considered temporary. For instance, repeating the request with incorrect credentials three or four times will not solve the authentication issue.
Logging Timeout Problems in Odoo
As soon as the developer runs into failure in integration, it is the server logs that get checked first. The timeout messages should assist in knowing what went wrong.
For instance:
_logger.warning(
"Timeout while synchronizing invoice %s",
invoice.name,
)
It must include the number of attempts made to synchronize.
At the same time, it should also be noted that the logs should not include sensitive information. Access tokens, passwords, API keys, and confidential request data must never be included even if they are useful for running a debug process.
What Should a Good Timeout Strategy Include?
In a good timeout strategy, there is no one-size-fits-all method for every Odoo integration. The exact approach primarily depends on the external service and the nature of the operation being carried out.
An effective implementation usually involves the following:
- The definition of a reasonable connection and response timeout.
- Clear mechanisms for timeout exception treatment.
- Limited retries.
- The application of increasing periods of time between retries.
- Different approaches to temporary and permanent errors.
- Use of idempotency or unique references for write operations.
- Keeping synchronization status in Odoo.
- Logging of useful information for failed attempts.
- Ability to retry records manually on demand.
An example of a synchronization record is moving from Pending to Processing status and then either to Completed or Failed. Another option is to receive a timeout request, but the record remains available for the next controlled attempt instead of being regarded as having synchronized successfully.
API timeouts are common place occurrences in working with third-party services, but the Odoo integration’s response to these APIs makes a big difference in overall system functionality. Correct request timeout settings prevent a client request from hanging forever, while having a proper approach to exception handling and retries allows resolving temporary issues. In addition, in case of operations leading to creating or modifying data, the developers should keep in mind that the third-party application may have performed the requested action while Odoo did not receive any replies. A proper combination of timeout processing techniques with proper logging, state synchronization, references, and idempotence will make Odoo integration more secure and easier to support.
To read more about How to Handle API Errors Effectively in Odoo 19, refer to our blog How to Handle API Errors Effectively in Odoo 19.