Index: src/org/openstreetmap/josm/actions/GpxExportAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/GpxExportAction.java	(revision 14727)
+++ src/org/openstreetmap/josm/actions/GpxExportAction.java	(working copy)
@@ -9,6 +9,7 @@
 import java.awt.event.KeyEvent;
 import java.io.File;
 import java.io.IOException;
+import java.nio.file.InvalidPathException;
 import java.text.MessageFormat;
 
 import javax.swing.JOptionPane;
@@ -20,7 +21,6 @@
 import org.openstreetmap.josm.gui.layer.Layer;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
-import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Shortcut;
 
 /**
@@ -107,8 +107,8 @@
             if (exporter.acceptFile(file, layer)) {
                 try {
                     exporter.exportData(file, layer);
-                } catch (IOException e) {
-                    Logging.error(e);
+                } catch (IOException | InvalidPathException e) {
+                    SaveActionBase.showAndLogException(e);
                 }
             }
         }
Index: src/org/openstreetmap/josm/actions/SaveActionBase.java
===================================================================
--- src/org/openstreetmap/josm/actions/SaveActionBase.java	(revision 14727)
+++ src/org/openstreetmap/josm/actions/SaveActionBase.java	(working copy)
@@ -6,6 +6,7 @@
 import java.awt.event.ActionEvent;
 import java.io.File;
 import java.io.IOException;
+import java.nio.file.InvalidPathException;
 import java.util.Collection;
 import java.util.LinkedList;
 import java.util.List;
@@ -25,6 +26,7 @@
 import org.openstreetmap.josm.spi.preferences.Config;
 import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Shortcut;
+import org.openstreetmap.josm.tools.Utils;
 
 /**
  * Abstract superclass of save actions.
@@ -120,8 +122,8 @@
                 ((OsmDataLayer) layer).onPostSaveToFile();
             }
             MainApplication.getMainFrame().repaint();
-        } catch (IOException e) {
-            Logging.error(e);
+        } catch (IOException | InvalidPathException e) {
+            showAndLogException(e);
             return false;
         }
         addToFileOpenHistory(file);
@@ -239,4 +241,17 @@
         history.add(0, filepath);
         PreferencesUtils.putListBounded(Config.getPref(), "file-open.history", maxsize, history);
     }
+
+    static void showAndLogException(Exception e) {
+        GuiHelper.runInEDT(() ->
+        JOptionPane.showMessageDialog(
+                MainApplication.getMainFrame(),
+                tr("<html>An error occurred while saving.<br>Error is:<br>{0}</html>",
+                        Utils.escapeReservedCharactersHTML(e.getClass().getSimpleName() + " - " + e.getMessage())),
+                tr("Error"),
+                JOptionPane.ERROR_MESSAGE
+                ));
+
+        Logging.error(e);
+    }
 }
Index: src/org/openstreetmap/josm/gui/io/importexport/FileExporter.java
===================================================================
--- src/org/openstreetmap/josm/gui/io/importexport/FileExporter.java	(revision 14727)
+++ src/org/openstreetmap/josm/gui/io/importexport/FileExporter.java	(working copy)
@@ -16,6 +16,7 @@
  */
 public abstract class FileExporter implements ActiveLayerChangeListener {
 
+    /** the  ExtensionFileFilter filter used by this exporter */
     public final ExtensionFileFilter filter;
 
     private boolean enabled;
Index: src/org/openstreetmap/josm/gui/io/importexport/GpxExporter.java
===================================================================
--- src/org/openstreetmap/josm/gui/io/importexport/GpxExporter.java	(revision 14727)
+++ src/org/openstreetmap/josm/gui/io/importexport/GpxExporter.java	(working copy)
@@ -10,7 +10,6 @@
 import java.io.File;
 import java.io.IOException;
 import java.io.OutputStream;
-import java.nio.file.InvalidPathException;
 import java.text.MessageFormat;
 import java.time.Year;
 import java.util.Optional;
@@ -38,7 +37,6 @@
 import org.openstreetmap.josm.spi.preferences.Config;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
 import org.openstreetmap.josm.tools.GBC;
-import org.openstreetmap.josm.tools.Logging;
 
 /**
  * Exports data to a .gpx file. Data may be native GPX or OSM data which will be converted.
@@ -205,13 +203,8 @@
             gpxData.put(META_KEYWORDS, keywords.getText());
         }
 
-        try (OutputStream fo = Compression.getCompressedFileOutputStream(file)) {
-            new GpxWriter(fo).write(gpxData);
-            fo.flush();
-        } catch (IOException | InvalidPathException ex) {
-            Logging.error(ex);
-            JOptionPane.showMessageDialog(MainApplication.getMainFrame(), tr("Error while exporting {0}:\n{1}", fn, ex.getMessage()),
-                    tr("Error"), JOptionPane.ERROR_MESSAGE);
+        try (OutputStream fo = Compression.getCompressedFileOutputStream(file); GpxWriter writer = new GpxWriter(fo)) {
+            writer.write(gpxData);
         }
     }
 
Index: src/org/openstreetmap/josm/gui/io/importexport/OsmExporter.java
===================================================================
--- src/org/openstreetmap/josm/gui/io/importexport/OsmExporter.java	(revision 14727)
+++ src/org/openstreetmap/josm/gui/io/importexport/OsmExporter.java	(working copy)
@@ -66,9 +66,11 @@
      * @param layer Data layer. Must be an instance of {@link OsmDataLayer}.
      * @param noBackup if {@code true}, the potential backup file created if the output file already exists will be deleted
      *                 after a successful export
+     * @throws IOException in case of IO errors
+     * @throws InvalidPathException when file name cannot be converted into a Path
      * @throws IllegalArgumentException if {@code layer} is not an instance of {@code OsmDataLayer}
      */
-    public void exportData(File file, Layer layer, boolean noBackup) {
+    public void exportData(File file, Layer layer, boolean noBackup) throws IOException {
         if (!(layer instanceof OsmDataLayer)) {
             throw new IllegalArgumentException(
                     MessageFormat.format("Expected instance of OsmDataLayer. Got ''{0}''.", layer.getClass().getName()));
@@ -80,9 +82,10 @@
         return Compression.getCompressedFileOutputStream(file);
     }
 
-    private void save(File file, OsmDataLayer layer, boolean noBackup) {
+    private void save(File file, OsmDataLayer layer, boolean noBackup) throws IOException {
         File tmpFile = null;
         try {
+
             // use a tmp file because if something errors out in the process of writing the file,
             // we might just end up with a truncated file.  That can destroy lots of work.
             if (file.exists()) {
@@ -97,13 +100,6 @@
             layer.onPostSaveToFile();
         } catch (IOException | InvalidPathException e) {
             Logging.error(e);
-            JOptionPane.showMessageDialog(
-                    MainApplication.getMainFrame(),
-                    tr("<html>An error occurred while saving.<br>Error is:<br>{0}</html>",
-                            Utils.escapeReservedCharactersHTML(e.getClass().getSimpleName() + " - " + e.getMessage())),
-                    tr("Error"),
-                    JOptionPane.ERROR_MESSAGE
-            );
 
             try {
                 // if the file save failed, then the tempfile will not be deleted. So, restore the backup if we made one.
@@ -120,6 +116,8 @@
                         JOptionPane.ERROR_MESSAGE
                 );
             }
+            // re-throw original error
+            throw e;
         }
     }
 
