Skip to content

Commit 2a350cf

Browse files
authored
Merge pull request #213 from lonvia/rollback-after-errors
Writer: roll back buffer after exceptions
2 parents fe34b21 + 2e65376 commit 2a350cf

File tree

2 files changed

+84
-0
lines changed

2 files changed

+84
-0
lines changed

lib/simple_writer.cc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ class SimpleWriter
3030

3131
void add_osmium_object(const osmium::OSMObject& o)
3232
{
33+
if (!buffer) {
34+
throw std::runtime_error{"Writer already closed."};
35+
}
36+
37+
buffer.rollback();
38+
3339
buffer.add_item(o);
3440
flush_buffer();
3541
}
@@ -40,6 +46,8 @@ class SimpleWriter
4046
throw std::runtime_error{"Writer already closed."};
4147
}
4248

49+
buffer.rollback();
50+
4351
if (py::isinstance<osmium::Node>(o)) {
4452
buffer.add_item(o.cast<osmium::Node &>());
4553
} else {
@@ -65,6 +73,8 @@ class SimpleWriter
6573
throw std::runtime_error{"Writer already closed."};
6674
}
6775

76+
buffer.rollback();
77+
6878
if (py::isinstance<osmium::Way>(o)) {
6979
buffer.add_item(o.cast<osmium::Way &>());
7080
} else {
@@ -88,6 +98,8 @@ class SimpleWriter
8898
throw std::runtime_error{"Writer already closed."};
8999
}
90100

101+
buffer.rollback();
102+
91103
if (py::isinstance<osmium::Relation>(o)) {
92104
buffer.add_item(o.cast<osmium::Relation &>());
93105
} else {

test/test_writer.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,3 +246,75 @@ def test_add_relation_after_close(tmp_path, simple_handler):
246246

247247
with pytest.raises(RuntimeError, match='closed'):
248248
simple_handler(node_opl, relation=lambda o: writer.add_relation(o))
249+
250+
251+
@pytest.mark.parametrize("final_item", (True, False))
252+
def test_catch_errors_in_add_node(tmp_path, final_item):
253+
test_file = tmp_path / 'test.opl'
254+
255+
writer = o.SimpleWriter(str(test_file), 4000)
256+
257+
try:
258+
writer.add_node(o.osm.mutable.Node(id=123))
259+
with pytest.raises(TypeError):
260+
writer.add_node(o.osm.mutable.Node(id=124, tags=34))
261+
if not final_item:
262+
writer.add_node(o.osm.mutable.Node(id=125))
263+
finally:
264+
writer.close()
265+
266+
output = test_file.read_text()
267+
268+
expected = 'n123 v0 dV c0 t i0 u T x y\n'
269+
if not final_item:
270+
expected += 'n125 v0 dV c0 t i0 u T x y\n'
271+
272+
assert output == expected
273+
274+
275+
@pytest.mark.parametrize("final_item", (True, False))
276+
def test_catch_errors_in_add_way(tmp_path, final_item):
277+
test_file = tmp_path / 'test.opl'
278+
279+
writer = o.SimpleWriter(str(test_file), 4000)
280+
281+
try:
282+
writer.add_way(o.osm.mutable.Way(id=123, nodes=[1, 2, 3]))
283+
with pytest.raises(TypeError):
284+
writer.add_way(o.osm.mutable.Way(id=124, nodes=34))
285+
if not final_item:
286+
writer.add_way(o.osm.mutable.Way(id=125, nodes=[11, 12]))
287+
finally:
288+
writer.close()
289+
290+
output = test_file.read_text()
291+
292+
expected = 'w123 v0 dV c0 t i0 u T Nn1,n2,n3\n'
293+
if not final_item:
294+
expected += 'w125 v0 dV c0 t i0 u T Nn11,n12\n'
295+
296+
assert output == expected
297+
298+
299+
@pytest.mark.parametrize("final_item", (True, False))
300+
def test_catch_errors_in_add_relation(tmp_path, final_item):
301+
test_file = tmp_path / 'test.opl'
302+
303+
writer = o.SimpleWriter(str(test_file), 4000)
304+
305+
try:
306+
writer.add_relation(o.osm.mutable.Relation(id=123))
307+
with pytest.raises(TypeError):
308+
writer.add_relation(o.osm.mutable.Relation(id=124, members=34))
309+
if not final_item:
310+
writer.add_relation(o.osm.mutable.Relation(id=125))
311+
finally:
312+
writer.close()
313+
314+
output = test_file.read_text()
315+
316+
expected = 'r123 v0 dV c0 t i0 u T M\n'
317+
if not final_item:
318+
expected += 'r125 v0 dV c0 t i0 u T M\n'
319+
320+
assert output == expected

0 commit comments

Comments
 (0)