nanci
nanci

Reputation: 431

How to extract error detail from traceback by using python regex?

I want to extract error detail from traceback, those tracebacks are extract from log file by using this method, and there are many different kinds of tracebacks, like below:

Traceback (most recent call last):
  File "/usr/lib/python2.7/runpy.py", line 174, in _run_module_as_main
    "__main__", fname, loader, pkg_name)
  File "/usr/lib/python2.7/runpy.py", line 72, in _run_code
    exec code in run_globals
  File "/root/env/common/test/test/__main__.py", line 5, in <module>
    main()
  File "/root/env/common/test/test/cli/parser.py", line 55, in main
    run_script(args)
  File "/root/env/common/test/test/cli/runner.py", line 124, in run_script
    exec_script(args.script, scope=globals(), root=True)
  File "/root/workspace/group/test_regression_utils.py", line 123, in exec_script
    cli_exec_script(*args,**kwargs)
  File "/root/env/common/test/test/cli/runner.py", line 186, in exec_script
    exec(compile(code, scriptpath, 'exec')) in scope
  File "shiju_12.py", line 30, in <module>

  File "/root/moaworkspace/group/testscript/utils/shiju_public.py", line 37, in shiju_move

Exception: close failed!
EndOfStream
EndOfStream
Traceback (most recent call last):
  File "/usr/lib/python2.7/runpy.py", line 174, in _run_module_as_main
    "__main__", fname, loader, pkg_name)
  File "/usr/lib/python2.7/runpy.py", line 72, in _run_code
    exec code in run_globals
  File "/root/env/common/test/test/__main__.py", line 5, in <module>
    main()
  File "/root/env/common/test/test/cli/parser.py", line 55, in main
    run_script(args)
  File "/root/env/common/test/test/cli/runner.py", line 124, in run_script
    exec_script(args.script, scope=globals(), root=True)
  File "/root/env/common/test/test/cli/runner.py", line 186, in exec_script
    exec(compile(code, scriptpath, 'exec')) in scope
  File "/root/env/common/mator/mator/mator.py", line 520, in start
    raise IOError("RPC server not started!")
IOError: RPC server not started

the expect result is:

("XXXX", "Exception: close failed!")
("XXXX","IOError: RPC server not started")

I have tried detail_regex = r'Traceback.*\n(\s+.*\n)*(.*)\n*' the second traceback is right, but the first traceback result is ("Exception: close failed!", "EndOfStream")

any ideas?

Upvotes: 0

Views: 1084

Answers (2)

Milovan Tomašević
Milovan Tomašević

Reputation: 8673

That will match:

  • Traceback \(most recent call last\): Match literally
  • (?:\n.*)+? Repeat in a non capturing group matching a newline followed by 0+ times any character
  • \n(.*?(?:Exception|Error):) Match newline and capturinggroup 0+ characters non greedy and than match Exception of Error followed by :`
  • \s* Match 0+ whitespace characters
  • (.+) Capturing group 1+ times any character

For example:

import re
import traceback


EXCEPTION_PATTERN = re.compile(
    r"Traceback \(most recent call last\):(?:\n.*)+?\n(.*?(?:Exception|Error):)\s*(.+)"
)


try:
    hello()
except Exception as ex:
    try:
        1/0
    except Exception as ex:
        ex_match = EXCEPTION_PATTERN.findall(traceback.format_exc())
        print(ex_match)

output:

[('NameError:', "name 'hello' is not defined"), ('ZeroDivisionError:', 'division by zero')]

If you need to count Exception / Error with details:

for i, data in enumerate(ex_match, start=1):
    print(f"No.{i} - {data[0]} {data[1]}")

output:

No.1 - NameError: name 'hello' is not defined
No.2 - ZeroDivisionError: division by zero

Upvotes: 0

sleepyhead
sleepyhead

Reputation: 25

If I change your pattern to Traceback.*\n(\s+.*\n)*(.*?)\n* it works for the given example. I am not sure though, that it solves your problem completely.

Upvotes: 1

Related Questions