How to get the actual file name in exception message in Databricks? - python-3.x

I am trying to figure out, how to get the actual file/module name in exception message in Databricks.
import traceback
def bad():
print("hello")
a = 1/0
def main():
try:
bad()
except Exception as e:
print(traceback.format_exc())
main()
When I run this the exception message I get like -
hello
Traceback (most recent call last):
File "<command-162594828857243>", line 8, in main
bad()
File "<command-162594828857243>", line 4, in bad
a = 1/0
ZeroDivisionError: division by zero
The "<command-162594828857243>" doesn't help at the time of debugging. I want the actual file/module name there.

Related

How to raise multiple exceptions of the same error in one 'Try' block

I am creating a program that lets you launch applications from Python. I had designed it so if a certain web browser was not downloaded, it would default to another one. Unfortunately, the try block seems to only function with one 'except FileNotFoundError.' Is there any way to have multiple of these in the same try block? Here's my (failing) code below:
app = input("\nWelcome to AppLauncher. You can launch your web browser by typing '1', your File Explorer by typing '2', or quit the program by typing '3': ")
if app == "1":
try:
os.startfile('chrome.exe')
except FileNotFoundError:
os.startfile('firefox.exe')
except FileNotFoundError:
os.startfile('msedge.exe')
If the user does not have Google Chrome downloaded, the program attempts to launch Mozilla Firefox. If that application is not found, it should open Microsoft Edge; instead it raises this error in IDLE (Please note that I have purposely misspelled chrome.exe and firefox.exe in order to simulate the programs essentially not existing):
Traceback (most recent call last):
File "C:/Users/NoName/AppData/Local/Programs/Python/Python38-32/applaunchermodule.py", line 7, in <module>
os.startfile('chome.exe')
FileNotFoundError: [WinError 2] The system cannot find the file specified: 'chome.exe'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:/Users/NoName/AppData/Local/Programs/Python/Python38-32/applaunchermodule.py", line 9, in <module>
os.startfile('frefox.exe')
FileNotFoundError: [WinError 2] The system cannot find the file specified: 'frefox.exe'
Is there any way to raise two of the same exceptions in a single try block?
for exe in ['chrome.exe','firefox.exe','msedge.exe']:
try:
os.startfile(exe)
break
except FileNotFoundError:
print(exe,"error")
For your exact case, I would suggest this:
priority_apps = ['chrome.exe', 'firefox.exe', 'msedge.exe'] # attempts to open in priority order
current_priority = 0
opened_app = False
while not opened_app and current_priority < len(priority_apps):
try:
os.startfile(priority_apps[current_priority])
opened_app = True
except Exception as e:
current_priority += 1
if not opened_app:
print("couldn't open anything! :(")
generic alternative with functions:
try:
do_something()
except Exception as e:
do_something_else1()
def do_something_else1():
try:
do_something()
except Exception as e:
do_something_else2()
generic alternative with nested try/except:
try:
do_something()
except Exception as e:
try:
do_something_else()
except Exception as e:
do_something_better()

Google PubSub - restarting subscription after exception raised

Good day,
I am running some long-running async jobs using PubSub to trigger a function. Occasionally, the task may fail. In such cases, I simply want to log the exception, acknowledge the message, and restart the subscription to ensure that the subscriber is still pulling new messages after the failure has occurred.
I have placed some simplified code to demonstrate my current set up below:
try:
while True:
streaming_pull_future = workers.subscriber.subscribe(
subscription_path, callback=worker_task <- includes logic to ack() the message if it's failed before
)
print(f'Listening for messages on {subscription_path}')
try:
streaming_pull_future.result()
except Exception as e:
print(streaming_pull_future.cancelled()) #<-- this evaluates to false
streaming_pull_future.cancel() #<-- this results in RunTimeError: set_result can only be called once.
print(e)
except KeyboardInterrupt: # seems to be an issue as per Github PubSub issue #17. No keyboard interrupt
streaming_pull_future.cancel()
I keep seeing a RuntimeError: set_result can only be called oncewhen I execute the streaming_pull_future.cancel() in the exception handler. I checked whether perhaps the subscriber had already been cancelled but when I logged out the status it evaluated to False. Yet when I then call the cancel() method I get the error. I want to ensure that any threads are cleaned up before making a new subscription in the case where I could have several errors. Does anyone know why this is happening and a way around it?
I am running Python 3.7.4 with PubSub 1.2.0 and grpcio 1.27.1.
Update:
As per comments, please see a reproducible example. The stack trace raised is included:
Listening for messages on projects/trigger-web-app/subscriptions/load-job-sub
968432700946405
Top-level exception occurred in callback while processing a message
Traceback (most recent call last):
File "C:\..\lib\site-packages\google\cloud\pubsub_v1\subscriber\_protocol\streaming_pull_manager.py", line
71, in _wrap_callback_errors
callback(message)
File "test.py", line 19, in worker_task
a = 1/0 # cause an exception to be raised
ZeroDivisionError: division by zero
968424309156485
Top-level exception occurred in callback while processing a message
Traceback (most recent call last):
File "C:\...\lib\site-packages\google\cloud\pubsub_v1\subscriber\_protocol\streaming_pull_manager.py", line
71, in _wrap_callback_errors
callback(message)
File "test.py", line 19, in worker_task
a = 1/0 # cause an exception to be raised
ZeroDivisionError: division by zero
Traceback (most recent call last):
File "test.py", line 29, in main
streaming_pull_future.result()
File "C:...\lib\site-packages\google\cloud\pubsub_v1\futures.py", line 105, in result
raise err
File "C:\...\lib\site-packages\google\cloud\pubsub_v1\subscriber\_protocol\streaming_pull_manager.py", line
71, in _wrap_callback_errors
callback(message)
File "test.py", line 19, in worker_task
a = 1/0 # cause an exception to be raised
ZeroDivisionError: division by zero
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "test.py", line 35, in <module>
main()
File "test.py", line 31, in main
streaming_pull_future.cancel()
File "C:\...\lib\site-packages\google\cloud\pubsub_v1\subscriber\futures.py", line 46, in cancel
return self._manager.close()
File "C:\...\lib\site-packages\google\cloud\pubsub_v1\subscriber\_protocol\streaming_pull_manager.py", line
496, in close
callback(self, reason)
File "C:\...\lib\site-packages\google\cloud\pubsub_v1\subscriber\futures.py", line 37, in _on_close_callback
self.set_result(True)
File "C:\...\lib\site-packages\google\cloud\pubsub_v1\futures.py", line 155, in set_result
raise RuntimeError("set_result can only be called once.")
RuntimeError: set_result can only be called once.
import os
from google.cloud import pubsub_v1
subscriber = pubsub_v1.SubscriberClient()
project_id=os.environ['GOOGLE_CLOUD_PROJECT']
subscription_name=os.environ['GOOGLE_CLOUD_PUBSUB_SUBSCRIPTION_NAME']
subscription_path = f'projects/{project_id}/subscriptions/{subscription_name}'
def worker_task( message ):
job_id = message.message_id
print(job_id)
a = 1/0 # cause an exception to be raised
message.ack()
def main():
streaming_pull_future = subscriber.subscribe(
subscription_path, callback=worker_task
)
print(f'Listening for messages on {subscription_path}')
try:
streaming_pull_future.result()
except Exception as e:
streaming_pull_future.cancel() # if exception in callback handler, this will raise a RunTimError
print(e)
if __name__ == '__main__':
main()
Thank you.

How do I catch an exception that occured within the target of a Process?

I am creating a process to execute a function. If the function raises an exception I am not able to catch it. The following is a sample code.
from multiprocessing import Process
import traceback
import time
class CustomTimeoutException(Exception):
pass
def temp1():
time.sleep(5)
print('In temp1')
raise Exception('I have raised an exception')
def main():
try:
p = Process(target=temp1)
p.start()
p.join(10)
if p.is_alive():
p.terminate()
raise CustomTimeoutException('Timeout')
except CustomTimeoutException as e:
print('in Custom')
print(e)
except Exception as e:
print('In exception')
print(e)
if __name__ == "__main__":
main()
When I run the above code the exception raised within temp1 does not get caught. Below is the sample output
In temp1
Process Process-1:
Traceback (most recent call last):
File "/usr/lib/python3.5/multiprocessing/process.py", line 249, in _bootstrap
self.run()
File "/usr/lib/python3.5/multiprocessing/process.py", line 93, in run
self._target(*self._args, **self._kwargs)
File "temp.py", line 12, in temp1
raise Exception('I have raised an exception')
Exception: I have raised an exception
I have also tried overwriting the run method of the Process class as mentioned in https://stackoverflow.com/a/33599967/9971556 Wasn't very helpful.
Expected output:
In exception
I have raised an exception

Python 3.X pycomm.ab_comm.clx CommError: must be str, not bytes

Im trying to get "PYCOMM" to connect to my CLX 5000 processor.
Every time I run my code I get:CommError: must be str, not bytes.
I have looked all over the code and I cant find where the issue is. Everything that is supposed to be in a string format is.
I am using python3.6
Here is the code:
import sys
from pycomm.ab_comm.clx import Driver as ClxDriver
c = ClxDriver()
if c.open('172.16.2.161'):
print(c.read_tag('Start'))
# Prints (1,'BOOL') if true; (0,'BOOL') if false
c.close()
Here is the error:
C:\Users\shirley\Miniconda3\python.exe C:/Users/shirley/Downloads/pycomm-pycomm3/pycomm-pycomm3/examples/test_clx_comm.py
Traceback (most recent call last):
File "C:\Users\shirley\Miniconda3\lib\site-packages\pycomm\cip\cip_base.py", line 617, in build_header
h += pack_uint(length) # Length UINT
TypeError: must be str, not bytes
The header is 24 bytes fixed length, and includes the command and the length of the optional data portion.
:return: the headre
"""
try:
h = command # Command UINT
**h += pack_uint(length) # Length UINT**
h += pack_dint(self._session) # Session Handle UDINT
h += pack_dint(0) # Status UDINT
h += self.attribs['context'] # Sender Context 8 bytes
h += pack_dint(self.attribs['option']) # Option UDINT
return h
except Exception as e:
raise CommError(e)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\shirley\Miniconda3\lib\site-packages\pycomm\cip\cip_base.py", line 786, in open
if self.register_session() is None:
File "C:\Users\shirley\Miniconda3\lib\site-packages\pycomm\cip\cip_base.py", line 635, in register_session
self._message = self.build_header(ENCAPSULATION_COMMAND['register_session'], 4)
File "C:\Users\shirley\Miniconda3\lib\site-packages\pycomm\cip\cip_base.py", line 624, in build_header
raise CommError(e)
pycomm.cip.cip_base.CommError: must be str, not bytes
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:/Users/shirley/Downloads/pycomm-pycomm3/pycomm-pycomm3/examples/test_clx_comm.py", line 5, in
if c.open('172.16.2.161'):
File "C:\Users\shirley\Miniconda3\lib\site-packages\pycomm\cip\cip_base.py", line 793, in open
raise CommError(e)
pycomm.cip.cip_base.CommError: must be str, not bytes
Process finished with exit code 1
After banging my head against wall trying to figure this out on my own.
I just switched to using PYLOGIX
https://github.com/dmroeder/pylogix
It worked the first time I ran it
and its reasonably fast.
I had the same problem:
TypeError: must be str, not bytes.
The error is because you are using Python 3.x, and I did the same thing: I used Python 3.6 instead of Python 2.6 or 2.7.
Change Python 3.x to 2.6 or 2.7 (I used 2.7).
This was a bug that was fixed recently
I have it working with pycomm#1.0.8 and python#3.7.3

How can I catch an error without using try/except?

Is there something that I could use to catch errors in python without using a try/except?
I'm thinking of something like this:
main.py
from catch_errors import catch_NameError
print(this_variable_is_not_defined)
catch_errors.py
def catch_NameError(error):
if type(error) == NameError:
print("You didn't define the error")
The output would be:
You didn't define the error
Instead of:
Traceback (most recent call last):
File "main.py", line 1, in <module>
print(this_variable_is_not_defined)
NameError: name 'this_variable_is_not_defined' is not defined
It can be done by creating a context manager, but it gives questionable benefit over an explicit try:except:. You will have to use the with statement, so it will be clear where behavior will change. In this example, I am using contextlib.contextmanager to do this, which saves the tedium of creating a class with __enter__ and __exit__ methods.
from contextlib import contextmanager
#contextmanager
def IgnoreNameErrorExceptions():
"""Context manager to ignore NameErrors."""
try:
yield
except NameError as e:
print(e) # You can print whatever you want here.
with IgnoreNameErrorExceptions():
print(this_variable_is_not_defined)
This will output
name 'this_variable_is_not_defined' is not defined

Resources