Lesson ยท 14 min
When a call fails
A call can fail
A model service runs on the computers of another company, and your program reaches it through a network. A call can fail for a reason that your code did not cause. A program that makes many calls gets each of these errors at some time.
| Error in this course | Cause | Status code of a real service | Does a new try help? |
|---|---|---|---|
AuthError |
The key is missing or wrong. | 401 | No. Correct the key. |
BadRequestError |
The call is wrong: the messages have a wrong form, the model does not exist, or the text is too long. | 400 | No. Correct the code. |
RateLimitError |
You sent too many calls or too many tokens in a short time. | 429 | Yes, after a wait. |
ServerError |
The service has a problem, or it has too much work. | 500 or 503 | Yes, after a wait. |
ModelTimeout |
The answer did not come in time. | None. Your program stopped the wait. | Yes. |
A real service answers each call with a status code, which is a number. The Python package of a service changes the status code into an error class. The names of the classes are different from service to service. The five groups are the same.
Two groups of errors
The last column of the table is the important one.
- A new try can help. The cause is temporary. The same call can work some seconds later.
- A new try cannot help. The call itself is wrong. It fails each time, until you change the key or the code.
A program that tries a wrong call again and again loses time, and it can reach the rate limit. A program that stops after one ServerError fails without need.
Catch the errors
Each error in Python has a class. The class is the name that you see in an error message, such as ValueError. The module sim_model has its own classes for the errors of the service.
Use try and except, as in lesson 8 of the course Python for data.
try:
response = client.chat(messages)
except RateLimitError as error:
print("Wait for", error.retry_after, "seconds.")
except ModelError as error:
print(type(error).__name__, str(error))
as errorgives the error a name, so that the block can read it.ModelErroris the parent class of the five errors.except ModelErrorcatches each of them.- Python uses the first
exceptblock that fits. So put a special class before its parent class. type(error).__name__is the name of the class of the error, such as"ServerError".str(error)is the text of the error.- A
RateLimitErrorhas the attributeretry_after. It is the number of seconds that the service asks you to wait.
Do not write except: without a class. It also catches a NameError from a typing mistake in your code, and then you do not see the mistake.
Errors on demand
The function plan of lesson 8 can also make a call fail.
| Step | What the call does |
|---|---|
"rate_limit" |
It raises a RateLimitError. |
"server_error" |
It raises a ServerError. |
"timeout" |
It raises a ModelTimeout. |
The simulated service raises an AuthError for a key that does not start with test-key. It raises a BadRequestError for a wrong call, such as an empty list of messages.
Your turn
main.py imports the error classes. Do the tasks in order.
Tasks
4 to do
Task 1, not checked yet. Write a function
can_retry(error). It returnsTruewhen the error is aRateLimitError, aServerErroror aModelTimeout. For each other error, it returnsFalse.Task 2, not checked yet. Write a function
try_chat(messages). It callsclient.chat(messages)in atryblock. When the call works, it returns{"ok": True, "content": ...}with the text of the answer. When the call raises aModelError, it returns{"ok": False, "error": ..., "retry": ...}with the name of the class of the error, and the result ofcan_retry.Task 3, not checked yet. Add the line
plan(["server_error", "ok"]). It tells the simulated service to fail one time and then to answer. After that line, calltry_chat(messages)two times. Store the results infirstandsecond. Then store the result oftry_chat([])inbad. Print the three results.Task 4, not checked yet. Make a second client with a wrong key:
guest = Client(api_key="guest"). Callguest.chat(messages)in atryblock. Catch theAuthError, and store the text of the error in a variableauth_message.
Task 1 of 4
Write a function can_retry(error). It returns True when the error is a RateLimitError, a ServerError or a ModelTimeout. For each other error, it returns False.