Skip to content

Missing Location header on a 2xx create raises a bare KeyError #44

Description

@tipatterson-dev

Problem

Every resource-creation method reads the new resource's id straight out of the Location response header, inside the if res.ok: branch:

  • System.insert_self()resources/system.py:568
  • System.add_insert_datastream()resources/system.py:398
  • System.add_insert_controlstream()resources/system.py:446
  • System.add_and_insert_control_stream()resources/system.py:530
  • Datastream.insert_observation_dict()resources/datastream.py:110

res.ok is true for any 2xx. A server that answers 200 OK or 204 No Content without a Location header — spec-legal, and what some proxies produce after stripping or rewriting headers — makes res.headers['Location'] raise a bare KeyError: 'Location'. The traceback points at a dict lookup, giving no hint that the POST actually succeeded and only the id is missing.

Reproduce

Point any of the above at a server (or proxy) that returns 2xx without Location. In a unit test:

capture_request(monkeypatch, "post", response=MockResponse(status=201))  # no headers
System(label="S", urn="urn:x:1", parent_node=node).insert_self()
# KeyError: 'Location'

Possible fix

Treat a missing Location as its own failure mode, with a message that says the POST succeeded but the id couldn't be recovered:

location = res.headers.get('Location')
if location is None:
    raise Exception(
        f'System {self.label!r} POST returned HTTP {res.status_code} but no '
        f'Location header; cannot determine the server-assigned id.'
    )

Same shape at all five sites. Since this is the fifth "the POST path needs a consistent error contract" item, the five bare raise Exception(...) calls are probably worth promoting to a typed exception at the same time.

Related: #42, #43.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions