Misleading error message after unhandled exception in wsadmin script - python

I'm developing an automation framework and I've experienced strange behavior of wsadmin tool. The problem is reproducible in WAS 6.1, 7.0 and 8.0 (I haven't tried with was 8.5).
I'm wondering if this is a bug in wsadmin (quite strange that nobody noticed it yet, probably since WAS 5!)...
The example scripts can be safely executed against any WAS environment without doing any harm.
try:
# this line throws WAS exception
AdminConfig.list('NonExistentType')
except:
# exception is being handled
print 'Handled wsadmin exception'
print 'Raising another exception'
# eventually the script throws a non-WAS exception
x = 1/0
If I understand correctly, the above script fails on zero-division. But wsadmin output is a bit confusing:
Handled wsadmin exception
Raising another exception
WASX7017E: Exception received while running file "ex.py"; exception information: com.ibm.websphere.management.exception.InvalidConfigDataTypeException
com.ibm.websphere.management.exception.InvalidConfigDataTypeException: ADMG0007E: The configuration data type NonExistentType is not valid.
What's really interesting, Jacl seems to have the same problem:
if [catch { puts [$AdminConfig list NonExistentType] } result] {
puts "Handled wsadmin exception"
}
puts "Raising another exception"
set x [expr 1 / 0]
wsadmin also does not print any information about the actual exception which terminated the script:
Handled wsadmin exception
Raising another exception
WASX7017E: Exception received while running file "ex.jacl"; exception information: com.ibm.websphere.management.exception.InvalidConfigDataTypeException
com.ibm.websphere.management.exception.InvalidConfigDataTypeException: ADMG0007E: The configuration data type NonExistentType is not valid.
After changing both scripts slightly (to avoid throwing WAS exception), the output of both scripts is correct.
try:
# this line does not throw any exception
AdminConfig.list('Cell')
except:
# exception is being handled
print 'Handled wsadmin exception'
print 'Raising another exception'
# eventually the script throws a non-WAS exception
x = 1/0
If the script doesn't throw/handle WAS exception, the output looks as expected:
Raising another exception
WASX7017E: Exception received while running file "ex1.py"; exception information: com.ibm.bsf.BSFException: exception from Jython:
Traceback (innermost last):
File "<string>", line 9, in ?
ZeroDivisionError: integer division or modulo
Same with Jacl:
if [catch { puts [$AdminConfig list Cell] } result] {
puts "Handled wsadmin exception"
}
puts "Raising another exception"
set x [expr 1 / 0]
wsadmin outputs the following, which again is quite expected:
wdrCell(cells/wdrCell|cell.xml#Cell_1)
Raising another exception
WASX7017E: Exception received while running file "ex1.jacl"; exception information: com.ibm.bsf.BSFException: error while eval'ing Jacl expression:
divide by zero
while executing
"expr 1 / 0"
invoked from within
"set x [expr 1 / 0]"
I have to confess a bit: the reason why I'm asking this question is that I actually reported the problem to WebSphere Support. I'm not fully satisfied with their replies though. Wsadmin/Jython/Jacl/Python/Tcl experts: what's your opinion on that?
Am I doing something wrong?
Is it a bug in wsadmin?
Is it expected behavior???

The problem will be fixed in upcoming FixPacks for WSAS 6.1, 7.0, 8.0 and 8.5.
IBM Support was a bit concerned about breaking compatibility with previous implementations (well, it's arguable, but some scripts may rely on this bug), therefore the proper behavior needs to be explicitly enabled using com.ibm.ws.scripting.exceptionPropagation=thrown JVM property.
I'm aware of two ways of passing this property to wsadmin's JVM:
javaOption environment variable
javaoption option
The environment variable way:
export javaOption=-Dcom.ibm.ws.scripting.exceptionPropagation=thrown
./wsadmin.sh -lang jython -f script.py
The command-line option way:
./wsadmin.sh -javaoption -Dcom.ibm.ws.scripting.exceptionPropagation=thrown-lang jython -f script.py
The fix solves the problem for both Jython and Jacl.
Link to official document: http://www-01.ibm.com/support/docview.wss?uid=swg1PM80400

Related

Automating RealTerm with Python

I am currently in the process of creating a script to automate RealTerm. I need to send a binary file and have the Winsock setting set to "Raw". RealTerms documentation indicates that I need an integer 0 or 1 for this setting but I am receiving a "object has no attribute" "Winsock".
RT.Winsock = 0 is what I currently have it set at. This this is the error message I get. '<win32com.gen_py.Realterm Library.IRealtermIntf instance at 0x1826368502752>' object has no attribute 'Winsock' Could this be a bug in the program?
I have also tried RT.Winsock = ("0") and that returned the same error but that sets it as a string and not integer.
Any thoughts on how it should be set or what I'm doing wrong?
Here is my full error below.
Exception has occurred: AttributeError
'<win32com.gen_py.Realterm Library.IRealtermIntf instance at 0x2390257155040>' object has no attribute 'Winsock'
During handling of the above exception, another exception occurred:
File "C:\NetworkUpdater\NUP\NUPv1.0.py", line 13, in module
RT.Winsock = 0
Edit: Added code below
RT = DispatchEx("Realterm.RealtermIntf")
RT.Visible = True
RT.Caption = "Realterm Controlled from Python"
RT.SelectTabSheet("Port")
RT.Winsock = 0
I was never able to get RT.Winsock to properly work or even use the DoCommands due to lack of examples even though it was in the documentation.
But I was able to resolve this issue and get the Wisock setting to Raw by setting WINSOCK=0 in a INI file that gets called upon startup of realterm.exe

In Python, how can the traceback module be used to find where an exception is generated?

I'm working on a convoluted FOSS project that utilizes GTK+3. When a flow graph is generated and attempted to run it, it generates the following error:
'Page' object has no attribute 'get_flow_graph'
There are 30 different files that have the generic "...object has no attribute..." exception listed in the code, and there are 4 files that call the function get_flow_graph().
So what I want to figure out is which of the 30 files that generate that particular error message is being executed, and preferably which of the 4 files with the function are causing the error in the first place.
I'm trying to use Python's traceback module to figure out where, specifically, the exception is being generated. I think I figured out the file that is calling the function that ultimately errors out, but I can't seem to get the traceback module to provide much more.
For example, if I wrap the function like this:
try:
fg = self.page.get_flow_graph()
except Exception:
traceback.print_exc()
then I just get
File "<redacted>", line 66, in _popen
fg = self.page.get_flow_graph()
AttributeError: 'Page' object has no attribute 'get_flow_graph'
'Page' object has no attribute 'get_proc'
as the output. So I get the original exception but a new get_proc error that doesn't help me but is obviously associated with trying to use traceback.
Maybe I'm not putting the trace in the correct file/location, or maybe I'm asking too much, but how should I write it to figure out the actual stack trace for the original AttributeError?
Does using
except AttributeError as e:
print(e.__traceback__.tb_lineno)
print(e.__traceback__.tb_frame)
instead, helps you further? (really asking, not being ironic)

Python still throwing exception I've explicitly excepted

I've got some code that I know will fail in the edge case where the list is empty so I added exception handling for IndexError.
But, despite handling the exception, it's still getting raised.
~/Code/foo.py in decode_tokens(tokens)
196 new_toks.append(new_tok)
197 else:
--> 198 try: new_toks[-1] += new_tok
199 except IndexError: pass
200 new_elem = True
IndexError: list index out of range
I don't understand how if I'm explicitly excepting IndexError why it's still getting raised and aborting script execution.
Edit: adding that this is Python 3.6 running in a Jupyter notebook. As it looked like a python error I didn't think that was relevant (but it sounds like it might be.)
Editors that support IPython, which include Jupyter, do not always reload modules even after they have been edited. I think this might be an unfortunate coincidence; the line that the error is thrown happens to coincide with the line of your exception handler after an edit. Likely the code that threw the error isn't what's at that line now. You may wish to force a reload of imported modules each time you run a script, or at least restart the underlying IPython kernel for now.

KeyError: 'getpwuid(): uid not found: 381206'

I'm running the following code to get owner of all files:
try:
st=os.stat(file_path)
uid=st.st_uid
userinfo=pwd.getpwuid(st.st_uid)
owner=pwd.getpwuid(st.st_uid).pw_name
file_info.append((size,file_path,owner))
except OSError as e:
pass
However, in the middle of the processing, it throws up the following error:
KeyError: 'getpwuid(): uid not found: 381206'
Do anyone know about this error? Are there any known issues with pwd in Python 2.6 ?
Please notice that this is just the part of the code I considered relevant, I can provide more if required.
The error happens in my python ver 3.5 as well in Linux.
In my case, once a person leaves the company, his/her UID is replaced with a number and pwd.getpwuid(st.st_uid) fails with the error.
I replaced it with sh.stat('-c', '%U', <path>).stdout.decode('utf-8').strip(), which returns UNKNOWN.

For this recursive code why does Python 2.7 not give a stack overflow error but 3.5 does?

Earlier today I read about this strange case in Python, Java & JS:
try:
return True
finally:
return False
Which returns False.
So, I decided to toy around with it:
def caseThree():
try:
caseThree()
except:
print("Error")
caseThree()
finally:
return False
print(caseThree())
In Python 2.7 this returns:
Error
False
However, in Python 3.5:
Error
Fatal Python error: Cannot recover from stack overflow.
Current thread 0x000025ec (most recent call first):
File "`<stdin>`", line 3 in caseThree
the last line is repeated until you eventually get: ...
Can anyone explain why 2.7's code doesn't result in a stack overflow, while 3.5 does?
It seems that the error you're encountering is actually expected, as it is explicitly tested for in Lib/test/test_sys.py function test_recursionlimit_fatalerror.
Now, without criticizing your colorful experiments, this is also the cause of a bug that causes a segfault (sometimes, see issue); there has already been one report of this to the Python bug tracker as issue 28179.
Keep an eye on that thread if you're curious as to what is causing this.

Categories