So, we had instance in the past where code were broken in IOT devices because of syntax errors.
While there is exception handling in the code. I wanted to create a script to check and make sure that the codes compiles and run without syntax error, else the script replace the broken code by an earlier version.
I tried this
from delta_script import get_update
def test_function():
try:
get_update()
except SyntaxError as syntaxError:
replace_script("utility.py", syntaxError)
except Exception as ignored:
pass
However the problem it when it hit a SyntaxError, it just throw it on the screen and replace_script
because the exception happens on delta_script.py from which get_update() was imported.
So what's the solution in this case?
I have also another function
def compile():
try:
for file in compile_list:
py_compile.compile(file)
except Exception as exception:
script_heal(file, exception)
however in this one, it never report any exception, because I go and introduce syntaxError and the code still compile without reporting an error
Any one could help me figure out a better way to solve those two problems?
thanks,
SyntaxErrors occur at compile time, not run time, so you generally can't catch them. There are exceptions, involving run time compilation using eval/exec, but in general, except SyntaxError: is nonsensical; something goes wrong compiling the code before it can run the code that sets up the try/except to catch the error.
The solution is to not write syntactically invalid code, or if you must write it (e.g. to allow newer Python syntax only when supported) to evaluate strings of said code dynamically with eval (often wrapping compile if you need something more complicated than a single expression) or exec.
Related
I want to catch exception while executing scipts/connecting to base using clickhouse_driver-drive dbapi.
Can I catch errors codes and errors message like
errorcodes.lookup(e.pgcode)
and
e.diag.message_primary
from
psycopg2.import errorcodes?
Assuming you're using the most well known clickhouse-driver from here: https://pypi.org/project/clickhouse-driver (GitHub here: https://github.com/mymarilyn/clickhouse-driver), you must catch standard exceptions/errors. Most errors are defined in the clickhouse_driver.connection module, and they include socket errors, EOF errors, and other lower level errors.
Even though the dbapi for that project defines exception classes, none of them are actually used in the code. The driver does not in any way use the errors or error codes from the PostgreSQL psycopg2 project.
I have a python file (app.py) which makes a call to a function as follows:
answer = fn1()
The fn1() is actually written in C++ and I've built a wrapper so that I can use it in Python.
The fn1() can either return a valid result, or it may sometimes fail and terminate. Now the issue is that at the times when fn1() fails and aborts, the calling file (i.e. app.py) also terminates and does not go forward to the error handling part.
I would like the calling file to move to my error handling part (i.e. 'except' and 'finally') if fn1() aborts and dumps core. Is there any way to achieve this?
From the OP:
The C++ file that I have built wrapper around aborts in case of exception and dumps core. Python error code is not executed
This was not evident in your question. To catch this sort of error, you can use the signal.signal function in the python standard library (relevant SO answer).
import signal
def sig_handler(signum, frame):
print("segfault")
signal.signal(signal.SIGSEGV, sig_handler)
answer = fn1()
You basically wrote the answer in your question. Use a try except finally block. Refer also to the Python3 documentation on error handling
try:
answer = fn1()
except Exception: # You can use an exception more specific to your failing code.
# do stuff
finally:
# do stuff
What you need to do is to catch the exception in your C++ function and then convert it to a python exception and return that to the python code.
If I understand correctly, when I run a Python program, the Python interpreter generates bytecode (the .pyc file that appears alongside the .py source) unless the source contains a syntax error.
Does the bytecode compiler generate any other exceptions or are all the other exceptions raised at runtime when the .pyc code is being executed?
Well, any exception type can technically be raised during runtime via raise <exception>. But I assume that you understand this and are asking what exceptions might be raised while Python interprets your code (before execution). There are actually quite a few:
SyntaxError: This is raised by the parser as it reads the code. It results from invalid syntax such as unbalanced parenthesis, using a keyword in the wrong place, etc.
IndentationError: This is a subclass of SyntaxError and is raised whenever your code has improper indentation. An example would be:
if condition:
line_indented_4_spaces
line_indented_3_spaces
TabError: This is a subclass of IndentationError and is raised when you inconsistently mix tabs and spaces in a source file.
SystemError: This is raised by the interpreter when an internal operation fails. Encountering one usually means that your Python installation is messed up and might need a reinstall.
MemoryError: This is similar to SystemError and can be raised when an internal operation fails for lack of memory.
All of these exceptions can be raised before your code even begins to execute. The first three are caused by a corrupt source file and can be resolved by simply fixing the syntax or indentation. The latter two however are raised by the interpreter itself for internal operations which fail. This means that they are rare, but also that they are more serious and not so easy to fix.
There is no compilation step typically when you're working with Python code so I would argue that all errors in Python, SyntaxErrors included, are runtime errors.
For example, lets write this file:
in xrange(5):
That's obviously just nonsense (we'll even name it nonsense.py), but lets fire up the interpreter:
$ python
>>> try:
... import nonsense
... except SyntaxError:
... print("A syntax error occurred at runtime!")
...
A syntax error occurred at runtime!
>>>
So there you have it - a SyntaxError was raised and caught at runtime, which, in my mind at least, indicates that it's a runtime error.
I am using django 1.2.7 and python 2.6.
If I use this code: (with an identation error on porpuse)
def myview(request):
try:
if x:
print 'x'
except:
return HttpResponseServerError('bazinga')
then I don't get my response. I get django 500 response.
but if I change the code to this:
def myview(request):
try:
if x:
print 'x'
except:
return HttpResponseServerError('bazinga')
now I get my own 500 with the bazinga written.
How can I catch the identation error in the first example ?
Just as my try-except catch the exception in the 2nd example.
Don't try to make Django return a nice response in the case of a syntax error. That will be difficult, and will involve having code of your own just for this case, and that code itself will need to be error-free, etc.
Instead, put that effort into an automated test suite that will make it easy to find those errors before you deploy your code.
Syntax errors can be detected trivially as you don't need to run the code but only to import it.
There's no reason you should try to catch them, just fix them.
You can catch syntax (And Indentation) errors out of your code.
Look here for more info:
How to catch IndentationError
Syntax errors are not run time errors, they occur at compile time. As far as I know, you can't catch them with a try/except block.
I'm writing some code to manipulate the Windows clipboard. The first thing I do is to try and open the clipboard with OpenClipboard() function from the Windows API:
if OpenClipboard(None):
# Access the clipboard here
else:
# Handle failure
This function can fail. So if it does, I would like to raise an exception. My question is, which of the standard Python exceptions should I raise? I'm thinking WindowsError would be the right one, but not sure. Could someone please give me a suggestion?
It is better to avoid raising standard exceptions directly. Create your own exception class, inherit it from the most appropriate one (WindowsError is ok) and raise it. This way you'll avoid confusion between your own errors and system errors.
Raise the windows error and give it some extra infomation, for example
raise WindowsError("Clipboard can't be opened")
Then when its being debugged they can tell what your windows error means rather than just a random windowserror over nothing.
WindowsError seems a reasonable choice, and it will record extra error information for you. From the docs:
exception WindowsError
Raised when a Windows-specific error occurs or when the error number does not correspond to an errno value. The winerror and strerror values are created from the return values of the GetLastError() and FormatMessage() functions from the Windows Platform API. The errno value maps the winerror value to corresponding errno.h values. ...