Python exception classes hierarchy is:

  • BaseException
    • Exception
      • OSError
        • RequestException *
        • TimeoutError

IOError that is a base class for RequestException have been merged with OSError after python version 3.3:

Changed in version 3.3: EnvironmentError, IOError, WindowsError, socket.error, select.error and mmap.error have been merged into OSError, and the constructor may return a subclass.

So as you can see RequestException is not a parent class of TimeoutError exception and can't be used to catch this type of errors:

import requests

try:
    raise TimeoutError('TIMEOUT ERROR')

except requests.exceptions.RequestException as e:
    # catch RequestException type errors that are specific for request library only
    # do something
    print("RequestExceptions will be caught")
 
except TimeoutError as e:
    # catch TimeoutError type errors that has same level in hierarchy as RequestException errors
    # do something
    print("TimeoutErrors will be caught")

except OSError as e:
    # catch all OSError type errors. Little bit wider than previous exceptions
    # do something
    print("TimeoutErrors or RequestExceptions or any other OSErrors will be caught")

except Exception as e:
    # catch any python errors, because all errors in python are children (sub types) for Exception class. Most wider exception type
    # do something
    print("TimeoutErrors or RequestExceptions or OSErrors or any other python errors will be caught")
Answer from rzlvmp on Stack Overflow
🌐
Requests
requests.readthedocs.io › en › latest › _modules › requests › exceptions
requests.exceptions — Requests 2.34.2 documentation
[docs] class TooManyRedirects(RequestException): """Too many redirects.""" class MissingSchema(RequestException, ValueError): """The URL scheme (e.g. http or https) is missing.""" class InvalidSchema(RequestException, ValueError): """The URL scheme provided is either invalid or unsupported.""" class InvalidURL(RequestException, ValueError): """The URL provided was somehow invalid.""" class InvalidHeader(RequestException, ValueError): """The header value provided was somehow invalid.""" class InvalidProxyURL(InvalidURL): """The proxy URL provided is invalid.""" class ChunkedEncodingError(Reques
🌐
GeeksforGeeks
geeksforgeeks.org › python › exception-handling-of-python-requests-module
Exception Handling Of Python Requests Module - GeeksforGeeks
July 23, 2025 - Python's requests module is a simple way to make HTTP requests. In this article, we’ll use the GET method to fetch data from a server and handle errors using try and except.
Discussions

My request-handling wrapper smells: any suggestions for best practices?
make_request will return to the caller either an error message or the actual response. Then the caller needs to have an if statement to determine what actually happened. There is a better way. Depending on the severity, Exceptions should bubble up to the caller. The caller should call "make_request" in a try/except block. If make_request gets back a response and a 200 OK, it returns that response and the caller goes about its business. This way you can also document that your function returns one specific thing. KISS principle. If make_request encounters an error, it will raise an exception with your error message and the caller will handle it in its except block. The Exceptions from requests, however, provide their own error messages so I don't know that you would need to create your own. Why not have the caller call requests directly and the except block will catch the above: try: do my request stuff except connectionException, readException, .... as my_error: print(my error) do other stuff except Exception as my_error: print("Unhandled exception. You should write something to handle it.") More on reddit.com
🌐 r/Python
14
8
December 11, 2017
Python requests errors out and I don't know how to catch the error - Stack Overflow
This is part of a script that iterates over our current ecommerce products and then checks stock at the distributor. This code is in a for loop, which is why the end of the except statement has &q... More on stackoverflow.com
🌐 stackoverflow.com
Intercept exception handling
I have a script I wrote that calls an API, crunches through some data, and displays it as text in the terminal. There is exception handling in the script in case of server problems (here is a cut-down example): cli_scri… More on discuss.python.org
🌐 discuss.python.org
3
0
April 14, 2023
exception - Correct way to try/except using Python requests module? - Stack Overflow
In the current form these will never be handled, as RequestException takes precedence (it's first on the list). 2024-02-04T08:47:24.187Z+00:00 ... Save this answer. ... Show activity on this post. Exception object also contains original response e.response, that could be useful if need to see error ... More on stackoverflow.com
🌐 stackoverflow.com
🌐
CodeSignal
codesignal.com › learn › courses › efficient-api-interactions-with-python › lessons › handling-errors-in-api-requests-1
Handling Errors in API Requests
Python's requests library comes with a handy method called raise_for_status(). This method is designed to simplify error detection by automatically raising an HTTPError for bad responses such as those with 4xx and 5xx status codes. Consider the following example, which fetches todo items from ...
🌐
Reddit
reddit.com › r/python › my request-handling wrapper smells: any suggestions for best practices?
r/Python on Reddit: My request-handling wrapper smells: any suggestions for best practices?
December 11, 2017 -

I'm working on a simple wrapper for requests.get that does basic error handling. Right now, if there are no errors, it just returns the response, but returns an error message otherwise. I'm now thinking it is smelly to have it return one data type (a Response) for success, and another (string with error message) for another. Is there a best practice for this sort of thing? Note the function below borrows ideas from a Stack Overflow thread on the topic.

Here is the function:

def make_request(url, session):
    """Wrapper for requests.get with basic error handling."""
    try:
        response = requests.get(url, headers = request_headers)
        if response.ok:
            return response
        else:
            response.raise_for_status()
    except requests.exceptions.ConnectTimeout as connectException:
        message = f"make_request - no connection to remote server: {connectException}.\nurl: {url}"
    except requests.exceptions.ReadTimeout as readException:
        message = f"make_request - timed out waiting for response: {readException}.\nurl: {url}"
    except requests.exceptions.InvalidURL as invalidException:
        message = f"make_request - invalid URL: {timeoutException}.\nurl: {url}"
    except requests.exceptions.HTTPError as invalidException:
        message = f"make_request - HTTP error: {httpException}.\nURL: {url}"
    except requests.exceptions.RequestException as requestException:
        message = f"make_request - exception raised: {requestError}.\nurl: {url}"
    return message
Top answer
1 of 5
2
make_request will return to the caller either an error message or the actual response. Then the caller needs to have an if statement to determine what actually happened. There is a better way. Depending on the severity, Exceptions should bubble up to the caller. The caller should call "make_request" in a try/except block. If make_request gets back a response and a 200 OK, it returns that response and the caller goes about its business. This way you can also document that your function returns one specific thing. KISS principle. If make_request encounters an error, it will raise an exception with your error message and the caller will handle it in its except block. The Exceptions from requests, however, provide their own error messages so I don't know that you would need to create your own. Why not have the caller call requests directly and the except block will catch the above: try: do my request stuff except connectionException, readException, .... as my_error: print(my error) do other stuff except Exception as my_error: print("Unhandled exception. You should write something to handle it.")
2 of 5
1
From what u/fiedzia said, I think my problem is I need to be better at exception handling. If anyone has any good references, I'm all ears. I also am wondering if there are any special considerations to use when handling requests in server-side scripts? Here is what I plan to read to bring me up to speed: https://jeffknupp.com/blog/2013/02/06/write-cleaner-python-use-exceptions/ https://julien.danjou.info/blog/2016/python-exceptions-guide http://www.codecalamity.com/exception-exception-read-all-about-it/ https://stackoverflow.com/questions/839636/best-practices-for-python-exceptions https://code.tutsplus.com/tutorials/professional-error-handling-with-python--cms-25950 https://eli.thegreenplace.net/2008/08/21/robust-exception-handling/ And maybe this to start with, with the caveat that it uses bare exceptions: https://www.codementor.io/sheena/how-to-write-python-custom-exceptions-du107ufv9
🌐
Python.org
discuss.python.org › python help
Intercept exception handling - Python Help - Discussions on Python.org
April 14, 2023 - I have a script I wrote that calls an API, crunches through some data, and displays it as text in the terminal. There is exception handling in the script in case of server problems (here is a cut-down example): cli_script.py def api_calls(): try: response = requests.get(login_url, headers=login_headers, verify=False) response.raise_for_status() except requests.exceptions.HTTPError: print("An error occurred: %s, %s" % ( json.loads(response.content)[...
Find elsewhere
🌐
TutorialsPoint
tutorialspoint.com › article › exception-handling-of-python-requests-module
Exception Handling Of Python Requests Module
March 27, 2026 - import requests class CustomAPIException(Exception): pass try: response = requests.get("https://httpbin.org/status/201") if response.status_code != 200: raise CustomAPIException(f"Unexpected status code: {response.status_code}") print("Request successful!") except requests.exceptions.RequestException as e: print("Request error occurred:", e) except CustomAPIException as e: print("Custom Exception:", e) ... Exception handling is essential when working with the Python Requests module to handle errors gracefully and ensure code reliability.
🌐
Medium
pavolkutaj.medium.com › exception-handling-of-python-requests-module-73dcdeb42aa4
Exception Handling Of Python Requests Module | by Pavol Z. Kutaj | Medium
October 11, 2022 - try: response = requests.get(url, auth=token) except: print("ERROR: Failed to establish connection") raise
Top answer
1 of 5
1405

Have a look at the Requests exception docs. In short:

In the event of a network problem (e.g. DNS failure, refused connection, etc), Requests will raise a ConnectionError exception.

In the event of the rare invalid HTTP response, Requests will raise an HTTPError exception.

If a request times out, a Timeout exception is raised.

If a request exceeds the configured number of maximum redirections, a TooManyRedirects exception is raised.

All exceptions that Requests explicitly raises inherit from requests.exceptions.RequestException.

To answer your question, what you show will not cover all of your bases. You'll only catch connection-related errors, not ones that time out.

What to do when you catch the exception is really up to the design of your script/program. Is it acceptable to exit? Can you go on and try again? If the error is catastrophic and you can't go on, then yes, you may abort your program by raising SystemExit (a nice way to both print an error and call sys.exit).

You can either catch the base-class exception, which will handle all cases:

try:
    r = requests.get(url, params={'s': thing})
except requests.exceptions.RequestException as e:  # This is the correct syntax
    raise SystemExit(e)

Or you can catch them separately and do different things.

try:
    r = requests.get(url, params={'s': thing})
except requests.exceptions.Timeout:
    # Maybe set up for a retry, or continue in a retry loop
except requests.exceptions.TooManyRedirects:
    # Tell the user their URL was bad and try a different one
except requests.exceptions.RequestException as e:
    # catastrophic error. bail.
    raise SystemExit(e)

As Christian pointed out:

If you want http errors (e.g. 401 Unauthorized) to raise exceptions, you can call Response.raise_for_status. That will raise an HTTPError, if the response was an http error.

An example:

try:
    r = requests.get('http://www.google.com/nothere')
    r.raise_for_status()
except requests.exceptions.HTTPError as err:
    raise SystemExit(err)

Will print:

404 Client Error: Not Found for url: http://www.google.com/nothere
2 of 5
217

One additional suggestion to be explicit. It seems best to go from specific to general down the stack of errors to get the desired error to be caught, so the specific ones don't get masked by the general one.

url='http://www.google.com/blahblah'

try:
    r = requests.get(url,timeout=3)
    r.raise_for_status()
except requests.exceptions.HTTPError as errh:
    print ("Http Error:",errh)
except requests.exceptions.ConnectionError as errc:
    print ("Error Connecting:",errc)
except requests.exceptions.Timeout as errt:
    print ("Timeout Error:",errt)
except requests.exceptions.RequestException as err:
    print ("OOps: Something Else",err)

Http Error: 404 Client Error: Not Found for url: http://www.google.com/blahblah

vs

url='http://www.google.com/blahblah'

try:
    r = requests.get(url,timeout=3)
    r.raise_for_status()
except requests.exceptions.RequestException as err:
    print ("OOps: Something Else",err)
except requests.exceptions.HTTPError as errh:
    print ("Http Error:",errh)
except requests.exceptions.ConnectionError as errc:
    print ("Error Connecting:",errc)
except requests.exceptions.Timeout as errt:
    print ("Timeout Error:",errt)     

OOps: Something Else 404 Client Error: Not Found for url: http://www.google.com/blahblah
🌐
Testmu
community.testmu.ai › t › best-way-to-handle-python-requests-exceptions › 34814
Best Way to Handle Python Requests Exceptions? - TestMu AI Community
January 8, 2025 - Is the following approach correct for handling exceptions using the Python requests module? try: r = requests.get(url, params={'s': thing}) except requests.ConnectionError as e: print(e) Is there a better way t…
🌐
YouTube
youtube.com › watch
Python Requests: Mastering Error Handling for Robust Web Interactions - YouTube
Explore the critical aspects of error handling in Python Requests library in this tutorial! Error handling is paramount for building robust web interactions,...
Published: November 14, 2024
🌐
Python documentation
docs.python.org › 3 › tutorial › errors.html
8. Errors and Exceptions — Python 3.14.7 documentation
If an exception occurs which does not match the exception named in the except clause, it is passed on to outer try statements; if no handler is found, it is an unhandled exception and execution stops with an error message.
🌐
LabEx
labex.io › tutorials › python-how-to-handle-different-http-status-codes-in-python-requests-398002
How to handle different HTTP status codes in Python requests | LabEx
Now that you understand the basics ... The requests library provides a convenient method called raise_for_status() that raises an exception for 4xx and 5xx status codes....
🌐
PVOutput Community
forum.pvoutput.org › api
Request for example python exception handling code (addstatus) - API - PVOutput Community
April 12, 2021 - An existing Python script that dumps serial smart meter data to InfluxDB every second is my starting point. The scripts stays running via a socat pipe. I managed to extend that script with a thread to gather metering data and post that information to the addstatus API every 5 minutes using requests.post.
🌐
Chainstack
docs.chainstack.com › web3 [de]coded › best practices handbook › best practices for error handling in api requests
Best practices for error handling in API requests - Chainstack
July 18, 2026 - Our retry logic aims to automatically retry the request when a temporary failure occurs. This can be a 5xx server error, a connection error, or any other type of error that we deem temporary. Here’s an example of how to implement retry logic in Python using both the response code and error messages to determine when to retry a request:
🌐
SecOps Hub
secopshub.com › t › handling-api-errors-using-python-requests › 589
Handling API errors using Python requests - SecOps - SecOps Hub
January 14, 2019 - I’m hoping this little code snippet will help someone else. I was writing a few functions in Python to interact with an API and wanted to stop processing any remaining code in the function, but I wanted to know why it failed at the calling level. So, here it is.
🌐
Reddit
reddit.com › r/learnpython › is requestexception any better than try/catch exception?
r/learnpython on Reddit: Is RequestException any better than try/catch Exception?
April 3, 2024 -

Is using the RequestsException class to catch errors considered good error handling? It feels a bit like using except Exception. I don't need to do a bunch of different things based on the kind of invalid response I get. I just need to know if the request was successful. Would this be considered "good" code?

from requests import RequestException
import requests
import traceback

def get_page_content(testURL:str) -> str | None:
    try:
        response = requests.get(testURL)
        return response.content
    except RequestException as error:
        print(f'{e} \n\n {traceback.format_exc()}')
        return None

Would something like this work better? Do all status codes between 200 and 399 mean I've probably got content I can use? I know 400 - 599 are bad. Except 418, that's gold, obviously.

from requests import RequestException

import requests import traceback
def get_page_content(testURL:str) -> str | None: 
    status_codes = [200,201,202,301,303] response = requests.get(testURL)
  # if 400 <= response.status_code < 600:
    if response.status in status_codes:
        return response.content
    else:
        print("Invalid Response.")
        return None
🌐
YouTube
youtube.com › john watson rooney
How To Handle Errors & Exceptions with Requests and Python - YouTube
Learning how to raise and handle your exceptions properly in Python is an extremely useful skill especially when paired with good logging. It enables you to ...
Published: October 11, 2021
Views: 16K
🌐
Apidog
apidog.com › blog › python-requests-response
The Ultimate Guide to Handling API Requests and ...
In this example, we're checking if the status code is in the 500 range, which indicates a server error. We're also handling 404 (Not Found) and 400 (Bad Request) errors. Now that we've covered the basics, let's explore some advanced tips and tricks to make your life easier when working with APIs in Python.
🌐
Real Python
realpython.com › python-requests
Python's Requests Library (Guide) – Real Python
July 23, 2025 - This tutorial guides you through customizing requests with headers and data, handling responses, authentication, and optimizing performance using sessions and retries. If you want to explore the code examples that you’ll see in this tutorial, then you can download them here: Get Your Code: Click here to download the free sample code that shows you how to use Python’s Requests library.