4

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
Daniel García Baena
  • 1,191
  • 4
  • 19
  • 33

2 Answers2

4

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.

idjaw
  • 25,487
  • 7
  • 64
  • 83
  • I see... And there's anyway to avoid this first log? – Daniel García Baena Aug 05 '17 at 14:35
  • 1
    You can play around with the log level for those modules I believe. Look at [this](https://stackoverflow.com/questions/11029717/how-do-i-disable-log-messages-from-the-requests-library) answer for some information on this to see if it helps you. – idjaw Aug 05 '17 at 14:36
  • 2
    I write here the working code: `logging.getLogger("requests.packages.urllib3").setLevel(logging.CRITICAL)` – Daniel García Baena Aug 05 '17 at 16:11
0

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

Chen A.
  • 10,140
  • 3
  • 42
  • 61