Skip to content

Commit 4363b57

Browse files
committed
indexer: more consistent and friendly error handling in auto indexer
1 parent ab2dad1 commit 4363b57

File tree

4 files changed

+32
-22
lines changed

4 files changed

+32
-22
lines changed

src/promnesia/common.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -301,9 +301,16 @@ def last(path: PathIsh, *parts: str) -> Path:
301301

302302
from .logging import setup_logger
303303

304+
from copy import copy
304305
def echain(ex: Exception, cause: Exception) -> Exception:
305-
ex.__cause__ = cause
306-
return ex
306+
e = copy(ex)
307+
e.__cause__ = cause
308+
# right.. even if we attach cause it doesn't help much because when we return/yield exception, we lose the stacktrace
309+
# so only 'ex' gets logged, cause is completely lost
310+
# hopefully this is safe? at least on runtimeerrors
311+
# might also do something smarter and collapes if both are strings or something..
312+
e.args += cause.args
313+
return e
307314

308315

309316
def slugify(x: str) -> str:

src/promnesia/sources/auto.py

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
import pytz
1919

20-
from ..common import Visit, Url, PathIsh, get_logger, Loc, get_tmpdir, extract_urls, Extraction, Results, mime, traverse, file_mtime
20+
from ..common import Visit, Url, PathIsh, get_logger, Loc, get_tmpdir, extract_urls, Extraction, Results, mime, traverse, file_mtime, echain, logger
2121
from ..config import use_cores
2222
from ..py37 import nullcontext
2323

@@ -91,12 +91,10 @@ def wrapped(path: Path):
9191
# ugh. keeping yeild in the try section is not ideal, but need this because of lazy yield semantics
9292
yield from it
9393
except ModuleNotFoundError as me:
94-
# TODO ugh. need to figure out how to attach cause/traceback
9594
logger = get_logger()
9695
logger.exception(me)
97-
logger.warn('while indexing "%s": %s not found, falling back to grep! "pip3 install --user %s" for better support!', path, me.name, me.name)
96+
logger.warn('%s: %s not found, falling back to grep! "pip3 install --user %s" for better support!', path, me.name, me.name)
9897
yield me
99-
10098
fallback_active[ex] = True
10199
do_fallback = True
102100
if do_fallback:
@@ -276,26 +274,35 @@ def _index_file(pp: Path, opts: Options) -> Results:
276274
yield from _index(path=uncomp, opts=opts)
277275
return
278276

277+
ex = RuntimeError(f'While indexing {pp}')
278+
279279
ip, pm = by_path(pp)
280280
if ip is None:
281281
# TOOD use warning (with mime/ext as key?)
282282
# TODO only log once? # hmm..
283283
msg = f'No extractor for suffix {suf}, mime {pm}'
284284
warnings.warn(msg)
285-
yield RuntimeError(msg + f', path {pp}')
285+
yield echain(ex, RuntimeError(msg))
286286
return
287287

288288
logger.debug('indexing via %s: %s', ip.__name__, pp)
289-
indexer: Union[Urls, Results] = ip(pp) # type: ignore
290-
# TODO careful, filter out obviously not plaintext? maybe mime could help here??
289+
290+
def indexer() -> Union[Urls, Results]:
291+
# eh, annoying.. need to make more generic..
292+
idx = ip(pp) # type: ignore
293+
try:
294+
yield from idx
295+
except Exception as e:
296+
yield e
291297

292298
root = opts.root
293299
fallback_dt = file_mtime(pp)
294300
fallback_loc = Loc.file(pp)
295301
replacer = opts.replacer
296-
for r in indexer:
302+
for r in indexer():
297303
if isinstance(r, Exception):
298-
yield r
304+
# indexers can rely on this method setting the error context
305+
yield echain(ex, r)
299306
continue
300307
if isinstance(r, EUrl):
301308
v = Visit(

src/promnesia/sources/markdown.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from pathlib import Path
33
from typing import Iterator, NamedTuple, Optional
44

5-
from ..common import get_logger, Extraction, Url, PathIsh, Res, Visit, echain, Loc, file_mtime
5+
from ..common import get_logger, Extraction, Url, PathIsh, Res, Visit, Loc, file_mtime, logger
66

77

88
import mistletoe # type: ignore
@@ -72,7 +72,7 @@ def _walk(self, cur, last_block) -> Iterator[Result]:
7272
try:
7373
yield from self._extract(cur, last_block)
7474
except Exception as e:
75-
# TODO log context??
75+
logger.exception(e)
7676
yield e
7777

7878
children = getattr(cur, 'children', [])
@@ -88,12 +88,10 @@ def extract_from_file(fname: PathIsh) -> Iterator[Extraction]:
8888
path = Path(fname)
8989
fallback_dt = file_mtime(path)
9090

91-
ex = RuntimeError(f'while extracting from {path}')
92-
9391
p = Parser(path)
9492
for r in p.walk():
9593
if isinstance(r, Exception):
96-
yield echain(ex, r)
94+
yield r
9795
else:
9896
yield Visit(
9997
url=r.url,

src/promnesia/sources/org.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from pathlib import Path
55

66

7-
from ..common import Visit, get_logger, Results, Url, Loc, from_epoch, echain, iter_urls, PathIsh, Res, file_mtime
7+
from ..common import Visit, get_logger, Results, Url, Loc, from_epoch, iter_urls, PathIsh, Res, file_mtime
88

99

1010
import orgparse
@@ -130,11 +130,9 @@ def extract_from_file(fname: PathIsh) -> Results:
130130

131131
fallback_dt = file_mtime(path)
132132

133-
ex = RuntimeError(f'while extracting from {fname}')
134-
135133
for wr in walk_node(node=root, dt=fallback_dt):
136134
if isinstance(wr, Exception):
137-
yield echain(ex, wr)
135+
yield wr
138136
continue
139137

140138
(parsed, node) = wr
@@ -148,7 +146,7 @@ def extract_from_file(fname: PathIsh) -> Results:
148146
# TODO not sure... perhaps keep the whole heading intact? unclear how to handle file tags though
149147
ctx = parsed.heading + tagss + '\n' + get_body_compat(node)
150148
except Exception as e:
151-
yield echain(ex, e)
149+
yield e
152150
ctx = 'ERROR' # TODO more context?
153151

154152
if isinstance(r, Url):
@@ -162,4 +160,4 @@ def extract_from_file(fname: PathIsh) -> Results:
162160
context=ctx,
163161
)
164162
else: # error
165-
yield echain(ex, r)
163+
yield r

0 commit comments

Comments
 (0)