Skip to content

Commit f588d34

Browse files
Merge pull request #5281 from nhsuk/fix-bundle-link-error
Warn instead of error for `Bundle.link` mismatch
2 parents ee9ee30 + 7721d42 commit f588d34

4 files changed

Lines changed: 313 additions & 4 deletions

File tree

app/lib/nhs/immunisations_api.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -430,8 +430,10 @@ def check_bundle_link_params(bundle, request_params)
430430

431431
unless tweaked_bundle_params == request_params ||
432432
bundle_params == request_params
433-
raise NHS::ImmunisationsAPI::BundleLinkParamsMismatch,
434-
"Bundle link parameters do not match request parameters: #{tweaked_bundle_params} != #{request_params}"
433+
message =
434+
"Bundle link parameters do not match request parameters: #{tweaked_bundle_params} != #{request_params}"
435+
Rails.logger.warn(message)
436+
Sentry.capture_exception(BundleLinkParamsMismatch.new(message))
435437
end
436438
end
437439

Lines changed: 277 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,277 @@
1+
{
2+
"resourceType": "Bundle",
3+
"type": "searchset",
4+
"link": [
5+
{
6+
"relation": "self",
7+
"url": "https://int.api.service.nhs.uk/immunisation-fhir-api/Immunization?-date.from=2025-08-01\u0026-date.to=2025-10-01\u0026immunization.target=FLU,HPV,MENACWY,3IN1,MMR\u0026patient.identifier=https%3A%2F%2Ffhir.nhs.uk%2FId%2Fnhs-number%7C9449308357"
8+
}
9+
],
10+
"entry": [
11+
{
12+
"fullUrl": "https://api.service.nhs.uk/immunisation-fhir-api/Immunization/4e7f3c91-a14d-4139-bbcf-859e998d2028",
13+
"resource": {
14+
"resourceType": "Immunization",
15+
"id": "4e7f3c91-a14d-4139-bbcf-859e998d2028",
16+
"extension": [
17+
{
18+
"url": "https://fhir.hl7.org.uk/StructureDefinition/Extension-UKCore-VaccinationProcedure",
19+
"valueCodeableConcept": {
20+
"coding": [
21+
{
22+
"system": "http://snomed.info/sct",
23+
"code": "884861000000100",
24+
"display": "Seasonal influenza vaccination (procedure)"
25+
}
26+
]
27+
}
28+
}
29+
],
30+
"identifier": [
31+
{
32+
"use": "official",
33+
"system": "http://manage-vaccinations-in-schools.nhs.uk/vaccination_records",
34+
"value": "71f538d8-1171-4204-aee4-17ff0b0ba0b0"
35+
}
36+
],
37+
"status": "completed",
38+
"vaccineCode": {
39+
"coding": [
40+
{
41+
"system": "http://snomed.info/sct",
42+
"code": "43208811000001106",
43+
"display": "Fluenz (trivalent) vaccine nasal suspension 0.2ml unit dose (AstraZeneca UK Ltd) (product)"
44+
}
45+
]
46+
},
47+
"patient": {
48+
"reference": "urn:uuid:e06dbb8d-ef9b-454f-9c5f-fde8460a0b6a",
49+
"type": "Patient",
50+
"identifier": {
51+
"system": "https://fhir.nhs.uk/Id/nhs-number",
52+
"value": "9449308357"
53+
}
54+
},
55+
"occurrenceDateTime": "2025-08-22T14:16:03+01:00",
56+
"recorded": "2025-08-22T14:16:05.246000+01:00",
57+
"primarySource": true,
58+
"location": {
59+
"identifier": {
60+
"system": "https://fhir.hl7.org.uk/Id/urn-school-number",
61+
"value": "100001"
62+
}
63+
},
64+
"manufacturer": {
65+
"display": "AstraZeneca"
66+
},
67+
"lotNumber": "BU5086",
68+
"expirationDate": "2025-09-30",
69+
"site": {
70+
"coding": [
71+
{
72+
"system": "http://snomed.info/sct",
73+
"code": "279549004",
74+
"display": "Nasal cavity structure"
75+
}
76+
]
77+
},
78+
"route": {
79+
"coding": [
80+
{
81+
"system": "http://snomed.info/sct",
82+
"code": "46713006",
83+
"display": "Nasal"
84+
}
85+
]
86+
},
87+
"doseQuantity": {
88+
"value": 0.2,
89+
"unit": "ml",
90+
"system": "http://snomed.info/sct",
91+
"code": "258773002"
92+
},
93+
"performer": [
94+
{
95+
"actor": {
96+
"type": "Organization",
97+
"identifier": {
98+
"system": "https://fhir.nhs.uk/Id/ods-organization-code",
99+
"value": "R1L"
100+
}
101+
}
102+
}
103+
],
104+
"reasonCode": [
105+
{
106+
"coding": [
107+
{
108+
"system": "http://snomed.info/sct",
109+
"code": "723620004"
110+
}
111+
]
112+
}
113+
],
114+
"protocolApplied": [
115+
{
116+
"targetDisease": [
117+
{
118+
"coding": [
119+
{
120+
"system": "http://snomed.info/sct",
121+
"code": "6142004",
122+
"display": "Influenza"
123+
}
124+
]
125+
}
126+
],
127+
"doseNumberPositiveInt": 1
128+
}
129+
]
130+
},
131+
"search": {
132+
"mode": "match"
133+
}
134+
},
135+
{
136+
"fullUrl": "https://api.service.nhs.uk/immunisation-fhir-api/Immunization/871f91fa-385e-4f42-8e0b-98e6c9a592dd",
137+
"resource": {
138+
"resourceType": "Immunization",
139+
"id": "871f91fa-385e-4f42-8e0b-98e6c9a592dd",
140+
"extension": [
141+
{
142+
"url": "https://fhir.hl7.org.uk/StructureDefinition/Extension-UKCore-VaccinationProcedure",
143+
"valueCodeableConcept": {
144+
"coding": [
145+
{
146+
"system": "http://snomed.info/sct",
147+
"code": "884861000000100",
148+
"display": "Seasonal influenza vaccination (procedure)"
149+
}
150+
]
151+
}
152+
}
153+
],
154+
"identifier": [
155+
{
156+
"use": "official",
157+
"system": "http://manage-vaccinations-in-schools.nhs.uk/vaccination_records",
158+
"value": "18441e7b-b652-4d8c-980c-b60009f95942"
159+
}
160+
],
161+
"status": "completed",
162+
"vaccineCode": {
163+
"coding": [
164+
{
165+
"system": "http://snomed.info/sct",
166+
"code": "43208811000001106",
167+
"display": "Fluenz (trivalent) vaccine nasal suspension 0.2ml unit dose (AstraZeneca UK Ltd) (product)"
168+
}
169+
]
170+
},
171+
"patient": {
172+
"reference": "urn:uuid:e06dbb8d-ef9b-454f-9c5f-fde8460a0b6a",
173+
"type": "Patient",
174+
"identifier": {
175+
"system": "https://fhir.nhs.uk/Id/nhs-number",
176+
"value": "9449308357"
177+
}
178+
},
179+
"occurrenceDateTime": "2025-08-26T12:48:01+01:00",
180+
"recorded": "2025-08-26T12:48:58.741000+01:00",
181+
"primarySource": true,
182+
"location": {
183+
"identifier": {
184+
"system": "https://fhir.hl7.org.uk/Id/urn-school-number",
185+
"value": "100005"
186+
}
187+
},
188+
"manufacturer": {
189+
"display": "AstraZeneca"
190+
},
191+
"lotNumber": "IK1741",
192+
"expirationDate": "2025-09-25",
193+
"site": {
194+
"coding": [
195+
{
196+
"system": "http://snomed.info/sct",
197+
"code": "279549004",
198+
"display": "Nasal cavity structure"
199+
}
200+
]
201+
},
202+
"route": {
203+
"coding": [
204+
{
205+
"system": "http://snomed.info/sct",
206+
"code": "46713006",
207+
"display": "Nasal"
208+
}
209+
]
210+
},
211+
"doseQuantity": {
212+
"value": 0.2,
213+
"unit": "ml",
214+
"system": "http://snomed.info/sct",
215+
"code": "258773002"
216+
},
217+
"performer": [
218+
{
219+
"actor": {
220+
"type": "Organization",
221+
"identifier": {
222+
"system": "https://fhir.nhs.uk/Id/ods-organization-code",
223+
"value": "R1L"
224+
}
225+
}
226+
}
227+
],
228+
"reasonCode": [
229+
{
230+
"coding": [
231+
{
232+
"system": "http://snomed.info/sct",
233+
"code": "723620004"
234+
}
235+
]
236+
}
237+
],
238+
"protocolApplied": [
239+
{
240+
"targetDisease": [
241+
{
242+
"coding": [
243+
{
244+
"system": "http://snomed.info/sct",
245+
"code": "6142004",
246+
"display": "Influenza"
247+
}
248+
]
249+
}
250+
],
251+
"doseNumberPositiveInt": 1
252+
}
253+
]
254+
},
255+
"search": {
256+
"mode": "match"
257+
}
258+
},
259+
{
260+
"fullUrl": "urn:uuid:e06dbb8d-ef9b-454f-9c5f-fde8460a0b6a",
261+
"resource": {
262+
"resourceType": "Patient",
263+
"id": "9449308357",
264+
"identifier": [
265+
{
266+
"system": "https://fhir.nhs.uk/Id/nhs-number",
267+
"value": "9449308357"
268+
}
269+
]
270+
},
271+
"search": {
272+
"mode": "include"
273+
}
274+
}
275+
],
276+
"total": 2
277+
}

spec/jobs/search_vaccination_records_in_nhs_job_spec.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,5 +659,24 @@
659659
include_examples "calls StatusUpdater"
660660
end
661661
end
662+
663+
context "with a mismatching `Bundle.link`" do
664+
let(:body) do
665+
file_fixture("fhir/search_response_mismatching_bundle_link.json").read
666+
end
667+
668+
it "raises a warning, and sends to Sentry" do
669+
expect(Rails.logger).to receive(:warn)
670+
expect(Sentry).to receive(:capture_exception).with(
671+
NHS::ImmunisationsAPI::BundleLinkParamsMismatch
672+
)
673+
674+
perform
675+
end
676+
677+
it "adds 2 vaccination records anyway" do
678+
expect { perform }.to change { patient.vaccination_records.count }.by(2)
679+
end
680+
end
662681
end
663682
end

spec/lib/nhs/immunisations_api_spec.rb

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -905,10 +905,21 @@
905905
}
906906
end
907907

908-
it "raises an error" do
909-
expect { perform_request }.to raise_error(
908+
it "raises a warning, and sends to Sentry" do
909+
expect(Rails.logger).to receive(:warn)
910+
expect(Sentry).to receive(:capture_exception).with(
910911
NHS::ImmunisationsAPI::BundleLinkParamsMismatch
911912
)
913+
914+
perform_request
915+
end
916+
917+
it "continues the job and consumes the records anyway" do
918+
expect(perform_request).to be_a FHIR::Bundle
919+
expect(perform_request.total).to be 2
920+
expect(perform_request.entry.size).to be 3
921+
expect(perform_request.entry[0].resource).to be_a FHIR::Immunization
922+
expect(perform_request.entry[1].resource).to be_a FHIR::Immunization
912923
end
913924
end
914925

0 commit comments

Comments
 (0)