Don't Log 'Certificate did not match expected hostname' Error Messages - python

My web app requests several URLs and sometimes SSL certificate errors are raised. They are all third party URLs so I can't fix their errors and I prefer not to log them. Nevertheless, something is logging this by itself: 2017-08-05 00:22:49,496 ERROR -- : Certificate did not match expected hostname: www.improving-autonomy.org. Certificate: {'subjectAltName': [('DNS', '*.wordpress.com'), ('DNS', 'wordpress.com')], 'subject': ((('commonName', u'*.wordpress.com'),),)} Anyone knows how can I stop it? Please find my code bellow. Many thanks in advance!
try :
ua = UserAgent()
headers = {'Content-Type' : 'text/html', 'Accept-Encoding' : None, 'User-Agent' : ua.random}
response = requests.get(url, headers=headers, timeout=10)
except ssl.CertificateError as e :
pass
UPDATED -- :
It looks like requests module logs it (connection.py). Why it keeps logging if I'm already catching the same exception?
def _match_hostname(cert, asserted_hostname):
try:
match_hostname(cert, asserted_hostname)
except CertificateError as e:
log.error(
'Certificate did not match expected hostname: %s. '
'Certificate: %s', asserted_hostname, cert
)
# Add cert to exception and reraise so client code can inspect
# the cert when catching the exception, if they want to
e._peer_cert = cert
raise

Sure. You are catching the same exception, but what you are not seeing is where this is happening. Let's take a look at the snippet of what is happening here:
except CertificateError as e:
log.error(
'Certificate did not match expected hostname: %s. '
'Certificate: %s', asserted_hostname, cert
)
# Add cert to exception and reraise so client code can inspect
# the cert when catching the exception, if they want to
e._peer_cert = cert
raise
So, when the exception is first raised, that code catches the CertificateError, then it makes a log.error, assigns the cert as an attribute, per the comment in the code, then, a call to raise is made.
That empty raise call is now going to re-raise the last exception made, which is the CertificateError exception, and that is what you are catching. So the log call has already been made by that code, and your exception catching is being made from that specific raise call.

You can catch the exception and then print it's type:
except Exception as exc:
print exc, exc.message, exc.__class__
Then use this specific exception type in your code, which should work. Also you can add an else clause after the except statement, and put the logging code there. This code will be executed only if the try block executed successfully

Related

Python Azure module error handling TCP 104 not being caught

I am currently using python 3.8.8 with version 12.9.0 of azure.storage.blob and 1.14.0 of azure.core.
I am downloading multiple files using the azure.storage.blob package. My code looks something like the following
from azure.storage.blob import ContainerClient
from azure.core.exceptions import ResourceNotFoundError, AzureError
from time import sleep
max_attempts = 5
container_client = ContainerClient(DETAILS)
for file in multiple_files:
attempts = 0
while attempts < max_attempts:
try:
data = container.download_blob(file).readall()
break
except ResourceNotFoundError:
# log missing data
break
except AzureError:
# This is mainly here as connections seem to drop randomly.
attempts += 1
sleep(1)
if attempts >= max_attempts:
#log connection error
#do something with the data.
It seems to be running fine, and I don't see any loss of data. However, within my terminal I keep getting the message
Unable to stream download: ("Connection broken: ConnectionResetError(104, 'Connection reset by peer')", ConnectionResetError(104, 'Connection reset by peer'))
This appears to be a TCP 104 return message but isn't being handled by the azure module. My questions are as follows.
Where is this message coming from? I can't see it in any of the packages I am using.
How do I handle this error better? It doesn't appear to be caught as an exception as it isn't crashing my code.
Can I get this to print to a log?
Where is this message coming from? I can't see it in any of the packages I am using.
Looks like The clients seemed to be connected to the server, but when they attempted to transfer data, they received a Errno 104 Connection reset by peer error. This also means, that the other side has reset the connection else the client would encounter with [Errno 32] Broken pipe exception.
How do I handle this error better? It doesn't appear to be caught as an exception as it isn't crashing my code.
One of the workarounds you can try is to have try and catch block to handle that exception:
from socket import error as SocketError
import errno
try:
response = urllib2.urlopen(request).read()
except SocketError as e:
if e.errno != errno.ECONNRESET:
raise # Not error we are looking for
pass # Handle error here.
Also try referring to this similar issue where sudo pip3 install urllib3 solved the issue.
Can I get this to print to a log?
One workaround is that you can pass exception instance in exc_info argument:
import logging
try:
1/0
except Exception as e:
logging.error('Error at %s', 'division', exc_info=e)
For more information you can refer How to log python exception?
Here is a related issue that you can follow up
azure storage blob download: ConnectionResetError(104, 'Connection reset by peer')
REFERENCE:
Connection broken: ConnectionResetError(104, 'Connection reset by peer') error while streaming

How to throw more than 1 possible exception for a single statement in python

I have this statement:
try:
cx_oracle..connect(username/password#hostname:port/service)
except cx_Oracle.DatabaseError:
#do_stuff
Let's say I provide a valid username, an empty password, an invalid hostname and an invalid service name; and I am writing conditions inside except block so that based on Oracle error code something will be done.
How can I list out all possible database errors without correcting the first error that has occurred?
Actual o/p: TNS: listener does not currently know of service requested
Required o/p: TNS: listener does not currently know of service requested
empty password
Invalid host
You can put multiple errors in a tuple. Then you can access whichever error with e.
try:
cx_oracle..connect(username/password#hostname:port/service)
except (cx_Oracle.DatabaseError, Error1, Error2) as e:
# do stuff
You can also have multiple excepts.
try:
cx_oracle..connect(username/password#hostname:port/service)
except cx_Oracle.DatabaseError:
# do stuff
except Error1:
# do stuff
I had a similar problem not too long ago, found this somewhere on stackoverflow, it catches multiple errors:
try:
cur.execute("insert into project_source_code(project, path) values(:project_id,:prj_path)",(project_id, prj_path))
except cx_Oracle.DatabaseError as e:
error, = e.args
print(error.code)
print(error.message)
print(error.context)

Flask cannot raise HTTP exception after try catching Runtime error

When I try to raise a HTTP exception status code 400 it only prints the json error message on the browser but does not state HTTP/1.1 400 BAD REQUEST in the console like it is supposed to. The exception raising works for all other parts of my program but it doesn't work when I do it in a try-catch for a runtime error.
My exception handler is exactly this:
http://flask.pocoo.org/docs/0.11/patterns/apierrors/
my try-catch:
try:
// run some program
catch RuntimeError as e:
raise InvalidUsage(e.message, status_code=400)
You should use the abort function of flask, something like:
from flask import abort
#app.route("/some_route")
def some_route():
try:
# do something
except SomeException:
abort(400, "Some message")

Python requests - Exception Type: ConnectionError - try: except does not work

I am using a webservice to retrieve some data but sometimes the url is not working and my site is not loading. Do you know how I can handle the following exception so there is no problem with the site in case the webservice is not working?
Django Version: 1.3.1
Exception Type: ConnectionError
Exception Value:
HTTPConnectionPool(host='test.com', port=8580): Max retries exceeded with url:
I used
try:
r = requests.get("http://test.com", timeout=0.001)
except requests.exceptions.RequestException as e: # This is the correct syntax
print e
sys.exit(1)
but nothing happens
You should not exit your worker instance sys.exit(1)
Furthermore you 're catching the wrong Error.
What you could do for for example is:
from requests.exceptions import ConnectionError
try:
r = requests.get("http://example.com", timeout=0.001)
except ConnectionError as e: # This is the correct syntax
print e
r = "No response"
In this case your program will continue, setting the value of r which usually saves the response to any default value

Are all HttpError in python subclasses of IOError

In our code we catch IOError and log it before reraising. I am getting a "connection reset by peer", but nothing in the logs. Is "connection reset by peer" a subclass of IOError in python?
.....
File "/usr/lib/python2.5/httplib.py", line 1047, in readline
s = self._read()
File "/usr/lib/python2.5/httplib.py", line 1003, in _read
buf = self._ssl.read(self._bufsize)
error: (104, 'Connection reset by peer')
The stack trace you pasted looks like some Exception of class error with arguments (104, 'Connection reset by peer).
So it looks like it's not a HTTPError exception at all. It looks to me like it's actually a socket.error. This class is indeed a subclass of IOError since Python 2.6.
But I guess that's not your question, since you are asking about HttpError exceptions. Can you rephrase your question to clarify your assumptions and expectations?
Comment from usawaretech:
How are you finding out it is a socket
error? MY code is something like:
try:risky_code(); except IOError:
logger.debug('...'); raise; As I am
assuming that HttpError is a subclass
of IOError, when I get that exception,
I am assuming that it be logged. There
is nothing in my logs
I guess it is a socket.error because I used the index of the standard library documentation, and because I encountered this error before.
What version of Python are you using? I guess it's Python 2.5 or earlier.
If your intent is to log and re-raise exceptions, it would be a better idea to use a bare except:
try:
risky_code()
except:
logger.debug(...)
raise
Also, you can find the module where the exception class was defined using exception.__module__.

Categories

Resources