Last active
March 21, 2021 19:05
-
-
Save mzpqnxow/404484ff4e02a73063816cd0190e329d to your computer and use it in GitHub Desktop.
Do basic processing on psycopg2 exceptions to print or map the Diagnostic object
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def psycopg2_diag_summarize(err: psycopg2.Error, formatted_lines: bool = False) -> Union[Dict, List[str]]: | |
"""Return a dict representation of a psycopg2.extensions.Diagnostics object | |
- Dynamically produce a dict for all public members of the object using dir() to get the | |
attribute names | |
- Filter out some undesirables (None, callables, non-localized versions of strings) | |
- Rename a fixed list of keys to make it more conducive to pretty-printing | |
Uses f-strings, so needs Python >= 3.6 | |
psycopg2 started exposing the Diagnostic object some time >= 2.5 | |
""" | |
av_map = {name: getattr(err.diag, name, None) for name in dir(err.diag) if not name.startswith('_') and not callable(getattr(err.diag, name))} | |
# Filter out None, callables and the "non-localized" version of strings (which are effectively duplicates for us) | |
f_map = {k: v for k, v in av_map.items() if v is not None and not callable(v) and not k.endswith('nonlocalized')} | |
source_file = f_map.pop('source_file', None) | |
source_function = f_map.pop('source_function', None) | |
source_line = f_map.pop('source_line', None) | |
f_map['Context'] = f_map.pop('context', None) | |
f_map['Source'] = f'{source_file}:{source_function}() :: {source_line}' | |
f_map['Error Message'] = f_map.pop('message_primary', 'N/A') | |
f_map['Error Message Detail'] = f_map.pop('message_detail', 'N/A') | |
f_map['SQL State'] = f_map.pop('sqlstate', 'N/A') | |
if formatted_lines is True: | |
# Return a bunch of lines so they can be called in context from a logger | |
lines = [ | |
f'===== psycopg2.extensions.Diagnostics Report =====', | |
f'===== EXCEPTION: {err.__class__.__name__} ====='] | |
for key, value in sorted(f_map.items()): | |
lines.append( f' diag.{key:<24} = {value}') | |
return lines | |
# Return a plain key/value mapping as a dict | |
return f_map |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment