handling exceptions from mechanize in python 2.7 - python

I have a small script that uses mechanize to go to a few websites to collect data. Sometimes the websites cause the script the crash and returns either "Bad Gateway" or "Connection Reset By Peer". I have an except line in the code so it emails me if there are any problems with the program, but I am trying to find a way to have it NOT email me in the case of these 2 problems. I've tried:
except Exception as e:
if 'Gateway' not in e and 'peer' not in e:
logger.error(e)
But this doesn't seem to work, as i still get emails if one of these 2 errors occur. What is the best way to have it email me in the case of any exception except for exceptions that contain certain text?

Instead of e in your if statement, use str(e).
except Exception as e:
if 'Gateway' not in str(e) and 'peer' not in str(e):
logger.error(e)

Related

W0703: Catching too general exception Exception (broad-except)

I'm using pylint to review one of my .py scripts and the below warning shows:
W0703: Catching too general exception Exception (broad-except)
This is an extract of the code.
try:
# Execute function1
function1()
logger.info('Function 1 successfully executed')
except Exception as e:
send_mail_error(str(e))
logger.error(str(e))
I would like to understand what is pylint suggesting here in order to improve it.
It is good practice to catch specific exception, read here.
In your case you want to log unknown exception and send email. In such case I am using SMTPHandler and custom sys.excepthook - like this.

Why asyncio raises TimeoutError without any message?

I encountered a small annoyance with this code:
try:
return await asyncio.wait_for(tcp_command(cmd), timeout=timeout)
except (OSError, asyncio.TimeoutError) as err:
print(f"Network problem: {err}")
When the timeout occurs, it prints just "Network problem: ". It is caused by an empty value attached to the raised asyncio.TimeoutError:
# inside wait_for():
raise futures.TimeoutError()
It is easy to hadle the TimeoutError separately, but I find the original construct quite idiomatic and now a core library breaks it. Is there a good reason for it? Is my assumption - that printing an exception should give us a clue what went wrong - correct?
Is there a good reason for it?
Yes, what kind of message you expect from TimeoutError? "Timeout occured"? The exception itself is self-explanatory, no need for such redundancy.
Is my assumption - that printing an exception should give us a clue what went wrong - correct?
Yes and no. Clue? Yes. Full information? No. The exception message is not mandatory. And the type of an exception is an important piece of information as well. And in many cases even more then the message itself.
So first of all: using print is wrong to begin with. Python has a very rich logging support. For example logger.exception(str(exc)) solves your problem because it logs entire traceback in addition to the message. At least by default, it can be customized.
But if you still want to use print then consider logging whole traceback:
import traceback
# traceback.print_exc()
print(traceback.format_exc())
If whole traceback is too big then you can always simply print the exception's class name:
# print(f'[{type(exc).__name__}] {exc}')
print(f'[{type(exc)}] {exc}')
or customize by exception:
try:
return await asyncio.wait_for(tcp_command(cmd), timeout=timeout)
except OSError as err:
print(f"Network problem: {err}")
except asyncio.TimeoutError:
print('Timeout occured')
The expectation that an exception will provide a message that explains the issue is not part of the general exception contract in Python. It is true for system exceptions such as OSError where the program must be able to get to the error message provided by the operating system, as the program is not qualified to guess the message based on a code or an exception subtype.
But more basic language exceptions do not work like that. Take, for example, KeyError raised by dict.__getitem__:
>>> try:
... d[123]
... except KeyError as err:
... print(f"Dict problem: {err}")
...
Dict problem: 123
In this sense, TimeoutError is much more like KeyError than like OSError. When you catch TimeoutError, you know exactly what happened - a timeout. You typically want to do something based on the fact that a timeout happened, rather than just display a message to the user. And even if you did want to provide a message, you'd use one that would make sense for your application, not a generic one provided by Python. This is in contrast to OSError where you often cannot do anything other than display the message coming from the OS and where that message can prove invaluable for investigating the underlying issue.
To sum it up, the problem is that you are catching two fundamentally different exceptions in the same except clause, and that set you up for trouble. I would restructure the code like this:
try:
return await asyncio.wait_for(tcp_command(cmd), timeout=timeout)
except OSError as err:
print(f"Network problem: {err}")
except asyncio.TimeoutError:
print("Operation timed out")

Handling Exceptions in Python 3.6

I am trying to handle exceptions in Python 3.6. I want to handle every possible exception and print the exception. When i do
try:
raise RuntimeError("Test")
except:
e = sys.exc_info()[0]
print(e)
it just prints
class '_mysql_exceptions.OperationalError'
How do i get the message of the Exception? In this case i would like the output to be "Test".
You can catch and print the Exception as follows:
try:
raise RuntimeError("Test")
except Exception as e:
print(e)
# Test
I'm not quite sure why you're trying to catch every Exception though, it would seem more prudent to let Python handle and raise these for you in general. Normally you would only catch specific Exceptions.
This behavior is not specific to Python 3.6.

python basic try catch exception

i wrote a code which is dumping numbers which is collected from serial port read as follows:
readoff = ser.readline()
and the proper format of readoff is follows:
a=' 213 -456 725'
and then for dumping and making some calculations im splitting it to 3 part and turning them to integer as follows:
splitted=readoff.split()
if len(splitted) == 3 :
temparrayforx.append(int(splitted[0]))
temparrayfory.append(int(splitted[1]))
temparrayforz.append(int(splitted[2]))
but sometimes from the serial port im reading something like: '2-264' which cannot turned into a integer. or sometimes readoff is not divisible to three.
here is my sample error:
temparrayforx.append(int(splitted[0]))
ValueError: invalid literal for int() with base 10: '2-264'
my goal is if the reading is not correct(if its not 3 part)(if its not a proper number), skip that readoff and go on(read another data). how can i do that ?
thanks for help
The standard python try-catch is:
try:
do_something_risky()
except ExceptionName as exc:
do_something_else()
It is very important to specify the exceptions you want to catch, otherwise you might catch unwanted exceptions that should bubble up, resulting in errors difficult to detect.
You can catch different exceptions and react in a different way to them:
try:
do_something_risky()
except SomeException as exc:
do_this()
except AnotherException as exc:
do_that()
Additionally you can add else and finally
try:
do_something_risky()
except ExceptionName, AnotherPossibleException as exc:
do_something_else()
else:
do_something_when_no_exception_raised()
finally:
# Useful for cleaning up
do_something_no_matter_what_happens()
In your case
try:
# Do the problematic thing
except ValueError as exc:
# Manage the exception
You should catch the specific exception that's being raised, ValueError in this case:
try:
temparrayforx.append(int(splitted[0]))
except ValueError as e:
print e
It's important to catch a specific error type so you don't accidentally catch lots of unexpected errors - like if splitted is empty, an IndexError would be raised. A bare 'except:' or 'except Exception:' would hide that from you.
In your case, since you want to catch a couple of different error cases (line doesn't have enough parts, value isn't a number) you can either catch both exception types in the same except clause or have two different except clauses - for example if you need to do different things with each problem.

Python Exception Handling - Best Practices

I'm writing a python program the accesses a database. I want to catch three types of exceptions when I make a http request. Timeouts, network errors, and http errors. I'm looking for the best way to deal with this situation. I need to check for these exceptions multiple times in multiple areas of my code, and it will look something like this each time:
try:
//some request
except timeout:
print '\nException: Timeout Error'
except connection error:
print '\nException: Network Error'
except http error, e:
print 'Exception: %s.' % e
Since I have to do this multiple times, at least probably 8 or more, should I make a module to handle these exceptions or no? Also in which of these cases would it be advisable to shut my system down as opposed to just displaying a message?
Thank you.
If you don't want to use decorators, you can also combine all the except statements, and use some function to handle your exception (assuming that your errors are called TimeoutError, ConnectionError, and HttpError...doesn't really matter for clarity) i.e.
try:
# do stuff
except (TimeoutError, ConnectionError, HttpError) as e:
handle_exception(e)

Categories

Resources