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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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