Index: /trunk/src/org/openstreetmap/josm/gui/ExceptionDialogUtil.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/ExceptionDialogUtil.java	(revision 15083)
+++ /trunk/src/org/openstreetmap/josm/gui/ExceptionDialogUtil.java	(revision 15084)
@@ -286,5 +286,5 @@
             msg = tr("Access to redacted version ''{0}'' of {1} {2} is forbidden.",
                     version, tr(type), id);
-        } else if (OsmApi.isUsingOAuth()) {
+        } else if (OsmApi.isUsingOAuth() && !ExceptionUtil.isUserBlocked(e)) {
             msg = ExceptionUtil.explainFailedOAuthAuthorisation(e);
         } else {
Index: /trunk/src/org/openstreetmap/josm/io/MessageNotifier.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/MessageNotifier.java	(revision 15083)
+++ /trunk/src/org/openstreetmap/josm/io/MessageNotifier.java	(revision 15084)
@@ -14,4 +14,5 @@
 import org.openstreetmap.josm.data.preferences.BooleanProperty;
 import org.openstreetmap.josm.data.preferences.IntegerProperty;
+import org.openstreetmap.josm.gui.ExceptionDialogUtil;
 import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
 import org.openstreetmap.josm.io.auth.CredentialsAgentException;
@@ -89,5 +90,5 @@
                 }
             } catch (OsmTransferException e) {
-                Logging.warn(e);
+                ExceptionDialogUtil.explainOsmTransferException(e);
             }
         }
Index: /trunk/src/org/openstreetmap/josm/io/OsmApiException.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/OsmApiException.java	(revision 15083)
+++ /trunk/src/org/openstreetmap/josm/io/OsmApiException.java	(revision 15084)
@@ -213,13 +213,19 @@
     public String getDisplayMessage() {
         StringBuilder sb = new StringBuilder();
-        if (errorHeader != null) {
-            sb.append(tr(errorHeader));
-            sb.append(tr("(Code={0})", responseCode));
-        } else if (errorBody != null && !errorBody.trim().isEmpty()) {
-            errorBody = errorBody.trim();
-            sb.append(tr(errorBody));
-            sb.append(tr("(Code={0})", responseCode));
+        String header = Utils.strip(errorHeader);
+        String body = Utils.strip(errorBody);
+        if ((header == null || header.isEmpty()) && (body == null || body.isEmpty())) {
+            sb.append(tr("The server replied an error with code {0}.", responseCode));
         } else {
-            sb.append(tr("The server replied an error with code {0}.", responseCode));
+            if (header != null && !header.isEmpty()) {
+                sb.append(tr(header));
+            }
+            if (body != null && !body.isEmpty()) {
+                if (sb.length() > 0) {
+                    sb.append(". ");
+                }
+                sb.append(tr(body));
+            }
+            sb.append(' ').append(tr("(Code={0})", responseCode));
         }
         return sb.toString();
Index: /trunk/src/org/openstreetmap/josm/tools/ExceptionUtil.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/tools/ExceptionUtil.java	(revision 15083)
+++ /trunk/src/org/openstreetmap/josm/tools/ExceptionUtil.java	(revision 15084)
@@ -2,4 +2,5 @@
 package org.openstreetmap.josm.tools;
 
+import static org.openstreetmap.josm.tools.I18n.marktr;
 import static org.openstreetmap.josm.tools.I18n.tr;
 import static org.openstreetmap.josm.tools.I18n.trn;
@@ -43,4 +44,10 @@
 public final class ExceptionUtil {
 
+    /**
+     * Error message sent by the OSM API when a user has been blocked.
+     */
+    private static final String OSM_API_BLOCKED =
+            marktr("Your access to the API has been blocked. Please log-in to the web interface to find out more.");
+
     private ExceptionUtil() {
         // Hide default constructor for utils classes
@@ -296,16 +303,5 @@
     public static String explainFailedAuthorisation(OsmApiException e) {
         Logging.error(e);
-        String header = e.getErrorHeader();
-        String body = e.getErrorBody();
-        String msg;
-        if (header != null) {
-            if (body != null && !header.equals(body)) {
-                msg = header + " (" + body + ')';
-            } else {
-                msg = header;
-            }
-        } else {
-            msg = body;
-        }
+        String msg = e.getDisplayMessage();
 
         if (msg != null && !msg.isEmpty()) {
@@ -726,4 +722,14 @@
     }
 
+    /**
+     * Determines if the OSM API exception has been thrown because user has been blocked.
+     * @param e OSM API exception
+     * @return {@code true} if the OSM API exception has been thrown because user has been blocked
+     * @since 15084
+     */
+    public static boolean isUserBlocked(OsmApiException e) {
+        return OSM_API_BLOCKED.equals(e.getErrorHeader());
+    }
+
     static String getUrlFromException(OsmApiException e) {
         if (e.getAccessedUrl() != null) {
Index: /trunk/test/unit/org/openstreetmap/josm/tools/ExceptionUtilTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/tools/ExceptionUtilTest.java	(revision 15083)
+++ /trunk/test/unit/org/openstreetmap/josm/tools/ExceptionUtilTest.java	(revision 15084)
@@ -11,7 +11,7 @@
 import java.util.TimeZone;
 
-import org.junit.BeforeClass;
+import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
-import org.openstreetmap.josm.JOSMFixture;
 import org.openstreetmap.josm.io.ChangesetClosedException;
 import org.openstreetmap.josm.io.IllegalDataException;
@@ -22,6 +22,9 @@
 import org.openstreetmap.josm.io.OsmApiInitializationException;
 import org.openstreetmap.josm.io.auth.CredentialsManager;
+import org.openstreetmap.josm.testutils.JOSMTestRules;
 import org.openstreetmap.josm.tools.date.DateUtils;
 import org.openstreetmap.josm.tools.date.DateUtilsTest;
+
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 
 /**
@@ -30,4 +33,11 @@
 public class ExceptionUtilTest {
 
+    /**
+     * Setup rule.
+     */
+    @Rule
+    @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
+    public JOSMTestRules test = new JOSMTestRules().preferences().fakeAPI();
+
     private static String baseUrl;
     private static String serverUrl;
@@ -39,9 +49,7 @@
      * @throws Exception in case of error
      */
-    @BeforeClass
-    public static void setUp() throws Exception {
-        JOSMFixture.createUnitTestFixture().init();
+    @Before
+    public void setUp() throws Exception {
         OsmApi api = OsmApi.getOsmApi();
-        api.initialize(null);
         baseUrl = api.getBaseUrl();
         serverUrl = api.getServerUrl();
@@ -154,11 +162,12 @@
     @Test
     public void testExplainFailedAuthorisation() {
-        assertEquals("<html>Authorisation at the OSM server failed.<br></html>",
+        assertEquals("<html>Authorisation at the OSM server failed.<br>The server reported the following error:<br>"+
+                "'The server replied an error with code 0.'</html>",
                 ExceptionUtil.explainFailedAuthorisation(new OsmApiException("")));
-        assertEquals("<html>Authorisation at the OSM server failed.<br>The server reported the following error:<br>'header'</html>",
+        assertEquals("<html>Authorisation at the OSM server failed.<br>The server reported the following error:<br>'header (Code=403)'</html>",
                 ExceptionUtil.explainFailedAuthorisation(new OsmApiException(HttpURLConnection.HTTP_FORBIDDEN, "header", null)));
-        assertEquals("<html>Authorisation at the OSM server failed.<br>The server reported the following error:<br>'header (body)'</html>",
+        assertEquals("<html>Authorisation at the OSM server failed.<br>The server reported the following error:<br>'header. body (Code=403)'</html>",
                 ExceptionUtil.explainFailedAuthorisation(new OsmApiException(HttpURLConnection.HTTP_FORBIDDEN, "header", "body")));
-        assertEquals("<html>Authorisation at the OSM server failed.<br>The server reported the following error:<br>'body'</html>",
+        assertEquals("<html>Authorisation at the OSM server failed.<br>The server reported the following error:<br>'body (Code=403)'</html>",
                 ExceptionUtil.explainFailedAuthorisation(new OsmApiException(HttpURLConnection.HTTP_FORBIDDEN, null, "body")));
     }
@@ -247,5 +256,5 @@
     @Test
     public void testExplainMissingOAuthAccessTokenException() {
-        assertEquals("<html>Failed to authenticate at the OSM server 'https://api06.dev.openstreetmap.org/api'.<br>"+
+        assertEquals("<html>Failed to authenticate at the OSM server 'http://fake.xxx/api'.<br>"+
                 "You are using OAuth to authenticate but currently there is no<br>OAuth Access Token configured.<br>"+
                 "Please open the Preferences Dialog and generate or enter an Access Token.</html>",
