Skip to content

Improve error details for Turtle undefined prefix #3451

Description

@nicholascar

If a Turtle file has an undefined prefix, you get an error like this:

Error in sys.excepthook:
Traceback (most recent call last):
  File "/Users/nick/work/ics/chart-data/.venv/lib/python3.14/site-packages/typer/main.py", line 86, in except_hook
    console_stderr.print(rich_tb)
    ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^
  File "/Users/nick/work/ics/chart-data/.venv/lib/python3.14/site-packages/rich/console.py", line 1731, in print
    extend(render(renderable, render_options))
    ~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/nick/work/ics/chart-data/.venv/lib/python3.14/site-packages/rich/console.py", line 1339, in render
    for render_output in iter_render:
                         ^^^^^^^^^^^
  File "/Users/nick/work/ics/chart-data/.venv/lib/python3.14/site-packages/rich/traceback.py", line 726, in __rich_console__
    yield render_stack(stack, last)
          ~~~~~~~~~~~~^^^^^^^^^^^^^
  File "/Users/nick/work/ics/chart-data/.venv/lib/python3.14/site-packages/rich/console.py", line 498, in _replace
    return Group(*renderables, fit=fit)
  File "/Users/nick/work/ics/chart-data/.venv/lib/python3.14/site-packages/rich/traceback.py", line 687, in render_stack
    highlighter(stack.syntax_error.msg),
    ~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/nick/work/ics/chart-data/.venv/lib/python3.14/site-packages/rich/highlighter.py", line 37, in __call__
    raise TypeError(f"str or Text instance required, not {text!r}")
TypeError: str or Text instance required, not None

Original exception was:
Traceback (most recent call last):
  File "/Users/nick/work/ics/chart-data/.venv/lib/python3.14/site-packages/rdflib/plugins/parsers/notation3.py", line 1245, in uri_ref2
    ns = self._bindings[pfx]
         ~~~~~~~~~~~~~~^^^^^
KeyError: 'geo'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/nick/work/ics/chart-data/.venv/bin/kurra", line 10, in <module>
    sys.exit(app())
             ~~~^^
  File "/Users/nick/work/ics/chart-data/.venv/lib/python3.14/site-packages/typer/main.py", line 1154, in __call__
    raise e
  File "/Users/nick/work/ics/chart-data/.venv/lib/python3.14/site-packages/typer/main.py", line 1137, in __call__
    return get_command(self)(*args, **kwargs)
           ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
  File "/Users/nick/work/ics/chart-data/.venv/lib/python3.14/site-packages/typer/_click/core.py", line 807, in __call__
    return self.main(*args, **kwargs)
           ~~~~~~~~~^^^^^^^^^^^^^^^^^
  File "/Users/nick/work/ics/chart-data/.venv/lib/python3.14/site-packages/typer/core.py", line 1193, in main
    return _main(
        self,
    ...<6 lines>...
        **extra,
    )
  File "/Users/nick/work/ics/chart-data/.venv/lib/python3.14/site-packages/typer/core.py", line 183, in _main
    rv = self.invoke(ctx)
  File "/Users/nick/work/ics/chart-data/.venv/lib/python3.14/site-packages/typer/core.py", line 1115, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
                           ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^
  File "/Users/nick/work/ics/chart-data/.venv/lib/python3.14/site-packages/typer/core.py", line 1115, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
                           ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^
  File "/Users/nick/work/ics/chart-data/.venv/lib/python3.14/site-packages/typer/_click/core.py", line 746, in invoke
    return ctx.invoke(self.callback, **ctx.params)
           ~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/nick/work/ics/chart-data/.venv/lib/python3.14/site-packages/typer/_click/core.py", line 489, in invoke
    return callback(*args, **kwargs)
  File "/Users/nick/work/ics/chart-data/.venv/lib/python3.14/site-packages/typer/main.py", line 1515, in wrapper
    return callback(**use_params)
  File "/Users/nick/work/ics/chart-data/.venv/lib/python3.14/site-packages/kurra/cli/commands/file.py", line 46, in reformat_command
    reformat(file_or_dir, check, output_format, output_filename)
    ~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/nick/work/ics/chart-data/.venv/lib/python3.14/site-packages/kurra/file.py", line 140, in reformat
    _format_file(
    ~~~~~~~~~~~~^
        path,
        ^^^^^
    ...<2 lines>...
        output_filename=output_filename,
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/Users/nick/work/ics/chart-data/.venv/lib/python3.14/site-packages/kurra/file.py", line 76, in _format_file
    content, changed = do_format(content, output_format)
                       ~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/nick/work/ics/chart-data/.venv/lib/python3.14/site-packages/kurra/file.py", line 30, in do_format
    graph = load_graph(content_no_comments)
  File "/Users/nick/work/ics/chart-data/.venv/lib/python3.14/site-packages/kurra/utils.py", line 103, in load_graph
    return Graph().parse(
           ~~~~~~~~~~~~~^
        data=graph_path_or_str,
        ^^^^^^^^^^^^^^^^^^^^^^^
        format=guess_format_from_data(graph_path_or_str),
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/Users/nick/work/ics/chart-data/.venv/lib/python3.14/site-packages/rdflib/graph.py", line 1669, in parse
    raise se
  File "/Users/nick/work/ics/chart-data/.venv/lib/python3.14/site-packages/rdflib/graph.py", line 1660, in parse
    parser.parse(source, self, **args)
    ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/nick/work/ics/chart-data/.venv/lib/python3.14/site-packages/rdflib/plugins/parsers/notation3.py", line 2034, in parse
    p.loadStream(stream)
    ~~~~~~~~~~~~^^^^^^^^
  File "/Users/nick/work/ics/chart-data/.venv/lib/python3.14/site-packages/rdflib/plugins/parsers/notation3.py", line 492, in loadStream
    return self.loadBuf(stream.read())  # Not ideal
           ~~~~~~~~~~~~^^^^^^^^^^^^^^^
  File "/Users/nick/work/ics/chart-data/.venv/lib/python3.14/site-packages/rdflib/plugins/parsers/notation3.py", line 498, in loadBuf
    self.feed(buf)
    ~~~~~~~~~^^^^^
  File "/Users/nick/work/ics/chart-data/.venv/lib/python3.14/site-packages/rdflib/plugins/parsers/notation3.py", line 524, in feed
    i = self.directiveOrStatement(s, j)
  File "/Users/nick/work/ics/chart-data/.venv/lib/python3.14/site-packages/rdflib/plugins/parsers/notation3.py", line 543, in directiveOrStatement
    j = self.statement(argstr, i)
  File "/Users/nick/work/ics/chart-data/.venv/lib/python3.14/site-packages/rdflib/plugins/parsers/notation3.py", line 791, in statement
    j = self.property_list(argstr, i, r[0])
  File "/Users/nick/work/ics/chart-data/.venv/lib/python3.14/site-packages/rdflib/plugins/parsers/notation3.py", line 1148, in property_list
    j = self.verb(argstr, i, v)
  File "/Users/nick/work/ics/chart-data/.venv/lib/python3.14/site-packages/rdflib/plugins/parsers/notation3.py", line 876, in verb
    j = self.prop(argstr, i, r)
  File "/Users/nick/work/ics/chart-data/.venv/lib/python3.14/site-packages/rdflib/plugins/parsers/notation3.py", line 887, in prop
    return self.item(argstr, i, res)
           ~~~~~~~~~^^^^^^^^^^^^^^^^
  File "/Users/nick/work/ics/chart-data/.venv/lib/python3.14/site-packages/rdflib/plugins/parsers/notation3.py", line 890, in item
    return self.path(argstr, i, res)
           ~~~~~~~~~^^^^^^^^^^^^^^^^
  File "/Users/nick/work/ics/chart-data/.venv/lib/python3.14/site-packages/rdflib/plugins/parsers/notation3.py", line 897, in path
    j = self.nodeOrLiteral(argstr, i, res)
  File "/Users/nick/work/ics/chart-data/.venv/lib/python3.14/site-packages/rdflib/plugins/parsers/notation3.py", line 1528, in nodeOrLiteral
    j = self.node(argstr, i, res)
  File "/Users/nick/work/ics/chart-data/.venv/lib/python3.14/site-packages/rdflib/plugins/parsers/notation3.py", line 1115, in node
    j = self.uri_ref2(argstr, i, res)
  File "/Users/nick/work/ics/chart-data/.venv/lib/python3.14/site-packages/rdflib/plugins/parsers/notation3.py", line 1253, in uri_ref2
    self.BadSyntax(argstr, i, 'Prefix "%s:" not bound' % (pfx))
    ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/nick/work/ics/chart-data/.venv/lib/python3.14/site-packages/rdflib/plugins/parsers/notation3.py", line 1743, in BadSyntax
    raise BadSyntax(self._thisDoc, self.lines, argstr, i, msg)
rdflib.plugins.parsers.notation3.BadSyntax: <no detail available>

This is not user-friendl. The important bit is the KeyError: 'geo' but even that is obscure and should be "Missing Prefix" or similar.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions