Skip to content

Commit fd19d9e

Browse files
committed
[FIX] Report: handle PermissionError when trying to save
https://sentry.io/biolab/orange3/issues/251030241/
1 parent e63c72b commit fd19d9e

File tree

2 files changed

+42
-7
lines changed

2 files changed

+42
-7
lines changed

Orange/canvas/report/owreport.py

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import os
2+
import logging
23

34
import pkg_resources
45
import pickle
@@ -21,6 +22,7 @@
2122
from Orange.canvas.application.canvasmain import CanvasMainWindow
2223
from Orange.canvas.gui.utils import message_critical
2324

25+
log = logging.getLogger(__name__)
2426

2527
class Column(IntEnum):
2628
item = 0
@@ -310,8 +312,11 @@ def save_report(self):
310312
self.save(filename)
311313
else:
312314
def save_html(contents):
313-
with open(filename, "w", encoding="utf-8") as f:
314-
f.write(contents)
315+
try:
316+
with open(filename, "w", encoding="utf-8") as f:
317+
f.write(contents)
318+
except PermissionError:
319+
self.permission_error(filename)
315320

316321
save_html(self.report_view.html())
317322
self.report_changed = False
@@ -337,14 +342,15 @@ def open_report(self):
337342

338343
try:
339344
report = self.load(filename)
340-
except (IOError, AttributeError) as e:
345+
except (IOError, AttributeError, pickle.UnpicklingError) as e:
341346
message_critical(
342347
self.tr("Could not load an Orange Report file"),
343348
title=self.tr("Error"),
344-
informative_text=self.tr("An unexpected error occurred "
345-
"while loading '%s'.") % filename,
349+
informative_text=self.tr("Error occurred "
350+
"while loading '{}'.").format(filename),
346351
exc_info=True,
347352
parent=self)
353+
log.error(str(e), exc_info=True)
348354
return
349355
self.set_instance(report)
350356
self = report
@@ -363,8 +369,11 @@ def save(self, filename):
363369
attributes=attributes,
364370
items=items)
365371

366-
with open(filename, 'wb') as f:
367-
pickle.dump(report, f)
372+
try:
373+
with open(filename, 'wb') as f:
374+
pickle.dump(report, f)
375+
except PermissionError:
376+
self.permission_error(filename)
368377

369378
@classmethod
370379
def load(cls, filename):
@@ -383,6 +392,16 @@ def load(cls, filename):
383392
)
384393
return self
385394

395+
def permission_error(self, filename):
396+
message_critical(
397+
self.tr("Permission error when trying to write report."),
398+
title=self.tr("Error"),
399+
informative_text=self.tr("Permission error occurred "
400+
"while saving '{}'.").format(filename),
401+
exc_info=True,
402+
parent=self)
403+
log.error("PermissionError when trying to write report.", exc_info=True)
404+
386405
def is_empty(self):
387406
return not self.table_model.rowCount()
388407

Orange/canvas/report/tests/test_report.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,22 @@ def test_report_table(self):
114114
'font-weight:normal;text-align:right;vertical-align:middle;">2</td>'
115115
'</tr></table>')
116116

117+
def test_save_report(self):
118+
"""
119+
Permission Error may occur when trying to save report.
120+
GH-2147
121+
"""
122+
rep = OWReport.get_instance()
123+
patch_target_1 = "Orange.canvas.report.owreport.open"
124+
patch_target_2 = "AnyQt.QtWidgets.QFileDialog.getSaveFileName"
125+
patch_target_3 = "AnyQt.QtWidgets.QMessageBox.exec_"
126+
filenames = ["f.report", "f.html"]
127+
for filename in filenames:
128+
with unittest.patch(patch_target_1, create=True, side_effect=PermissionError),\
129+
unittest.patch(patch_target_2, return_value=(filename, 0)),\
130+
unittest.patch(patch_target_3, return_value=True):
131+
rep.save_report()
132+
117133

118134
class TestReportWidgets(WidgetTest):
119135
model_widgets = MODEL_WIDGETS

0 commit comments

Comments
 (0)