Skip to content

Skip coordinates that Geo::Coord rejects instead of raising - #105

Open
thatbudakguy wants to merge 1 commit into
mainfrom
navplace-invalid-coordinates
Open

thatbudakguy wants to merge 1 commit into
mainfrom
navplace-invalid-coordinates

Conversation

@thatbudakguy

Copy link
Copy Markdown
Collaborator

Why

NavPlace#valid? is documented as "indicates if coordinate_texts passed in are valid", and it returns false for text that doesn't match COORD_REGEX. But when text does match the regex and Geo::Coord then rejects the result, the ArgumentError propagates straight out of valid? — so the predicate meant to guard against invalid input raises on it instead.

Callers doing exactly what the API invites still get an exception:

nav_place.valid? ? nav_place.build : nil  # raises ArgumentError

This is a live 500 in sul-dlss/purl's IIIF manifest endpoint. Geo::Coord rejects two things that turn up in real MARC coordinate data, both reaching us from cataloged Stanford records:

coordinate text Geo::Coord error
W 008°00′00″--W 004°00′00″/N 059°00′00″--N 543°00′00″ Expected latitude to be between -90 and 90, 0.543e3 received
(W 117°57'--W 117°39'/E 34°50'--E 32°48'). Unidentified hemisphere: E — latitudes labeled E

The second is the more interesting shape: the degrees are in range, but the hemisphere belongs to the wrong axis.

What changed

coord_for rescues ArgumentError and returns nil, which is already how the method reports text it can't use (return unless long_matcher && lat_matcher). So an unusable coordinate is skipped by the existing .compact, valid? reports false, and build raises its own 'invalid coordinates' only when nothing usable is left.

Rescuing in coord_for rather than in valid? matters: build, features, and polygon_geometry all reach coordinates too, so a narrower fix would still leave build able to raise a raw Geo::Coord error.

Verification

  • Full suite: 1034 examples, 0 failures (1 pre-existing pending), up from 1029. No existing expectations changed.
  • New specs cover both rejection modes for #valid? and #build, using the real record values above, plus a mixed case asserting that one unusable coordinate is skipped while the valid ones still build.

NavPlace#valid? is documented to indicate whether the coordinate texts are
valid, and it returns false for text that does not match COORD_REGEX. But when
text matches the regex and Geo::Coord then rejects the result, the ArgumentError
propagated out of valid?, so a predicate meant to guard against invalid input
raised on it instead. Callers that did the documented thing --
`nav_place.valid? ? nav_place.build : nil` -- still got an exception.

Geo::Coord rejects two things that occur in real MARC coordinate data: degrees
outside the valid range ("N 543°00′00″"), and a hemisphere that does not belong
to the axis it was given for ("E 34°50′" as a latitude). coord_for now returns
nil for both, the same as text that did not match at all, so the coordinate is
skipped, valid? reports false, and build raises its own 'invalid coordinates'
error only when nothing usable is left.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant