Bug 1400359 - show user alert if pop server cannot be reached. r=frg a=jorgk
authorJorg K <jorgk@jorgk.com>
Tue, 19 Sep 2017 00:27:38 +0200
changeset 28608 f26b00899997420bbb3ea06037a4487f4ce30de2
parent 28607 eca90d4a27d2e1e30c7ddcfddddda5be2227b967
child 28609 9ccf7f64ce420ef440989f27cf70e6769aee01d9
push id2020
push usermozilla@jorgk.com
push dateThu, 21 Sep 2017 15:25:57 +0000
treeherdercomm-beta@430b691235dc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfrg, jorgk
bugs1400359
Bug 1400359 - show user alert if pop server cannot be reached. r=frg a=jorgk
mailnews/base/util/nsMsgProtocol.cpp
mailnews/base/util/nsMsgProtocol.h
mailnews/local/src/nsPop3Protocol.cpp
--- a/mailnews/base/util/nsMsgProtocol.cpp
+++ b/mailnews/base/util/nsMsgProtocol.cpp
@@ -323,82 +323,84 @@ NS_IMETHODIMP nsMsgProtocol::OnStartRequ
 
   if (strans)
     strans->SetTimeout(nsISocketTransport::TIMEOUT_READ_WRITE, gSocketTimeout);
 
   NS_ENSURE_SUCCESS(rv, rv);
   return rv;
 }
 
+void nsMsgProtocol::ShowAlertMessage(nsIMsgMailNewsUrl *aMsgUrl, nsresult aStatus)
+{
+  const char16_t* errorString = nullptr;
+  switch (aStatus)
+  {
+  case NS_ERROR_UNKNOWN_HOST:
+  case NS_ERROR_UNKNOWN_PROXY_HOST:
+     errorString = u"unknownHostError";
+     break;
+  case NS_ERROR_CONNECTION_REFUSED:
+  case NS_ERROR_PROXY_CONNECTION_REFUSED:
+     errorString = u"connectionRefusedError";
+     break;
+  case NS_ERROR_NET_TIMEOUT:
+     errorString = u"netTimeoutError";
+     break;
+  default:
+     // Leave the string as nullptr.
+     break;
+  }
+
+  NS_ASSERTION(errorString, "unknown error, but don't alert user.");
+  if (errorString)
+  {
+    nsString errorMsg;
+    errorMsg.Adopt(FormatStringWithHostNameByName(errorString, aMsgUrl));
+    if (errorMsg.IsEmpty())
+    {
+      errorMsg.Assign(NS_LITERAL_STRING("[StringID "));
+      errorMsg.Append(errorString);
+      errorMsg.AppendLiteral("?]");
+    }
+
+    nsCOMPtr<nsIMsgMailSession> mailSession =
+      do_GetService(NS_MSGMAILSESSION_CONTRACTID);
+    if (mailSession)
+      mailSession->AlertUser(errorMsg, aMsgUrl);
+  }
+}
+
 // stop binding is a "notification" informing us that the stream associated with aURL is going away.
 NS_IMETHODIMP nsMsgProtocol::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult aStatus)
 {
   nsresult rv = NS_OK;
 
   // if we are set up as a channel, we should notify our channel listener that we are starting...
   // so pass in ourself as the channel and not the underlying socket or file channel the protocol
   // happens to be using
   if (!mSuppressListenerNotifications && m_channelListener)
     rv = m_channelListener->OnStopRequest(this, m_channelContext, aStatus);
 
   nsCOMPtr <nsIMsgMailNewsUrl> msgUrl = do_QueryInterface(ctxt, &rv);
   if (NS_SUCCEEDED(rv) && msgUrl)
   {
-    rv = msgUrl->SetUrlState(false, aStatus);
+    rv = msgUrl->SetUrlState(false, aStatus);  // Always returns NS_OK.
     if (m_loadGroup)
       m_loadGroup->RemoveRequest(static_cast<nsIRequest *>(this), nullptr, aStatus);
 
     // !m_channelContext because if we're set up as a channel, then the remove
     // request above will handle alerting the user, so we don't need to.
     //
     // !NS_BINDING_ABORTED because we don't want to see an alert if the user
     // cancelled the operation.  also, we'll get here because we call Cancel()
     // to force removal of the nsSocketTransport.  see CloseSocket()
     // bugs #30775 and #30648 relate to this
     if (!m_channelContext && NS_FAILED(aStatus) &&
         (aStatus != NS_BINDING_ABORTED))
-    {
-      const char16_t* errorString = nullptr;
-      switch (aStatus)
-      {
-          case NS_ERROR_UNKNOWN_HOST:
-          case NS_ERROR_UNKNOWN_PROXY_HOST:
-             errorString = u"unknownHostError";
-             break;
-          case NS_ERROR_CONNECTION_REFUSED:
-          case NS_ERROR_PROXY_CONNECTION_REFUSED:
-             errorString = u"connectionRefusedError";
-             break;
-          case NS_ERROR_NET_TIMEOUT:
-             errorString = u"netTimeoutError";
-             break;
-          default:
-             // Leave the string as nullptr.
-             break;
-      }
-
-      NS_ASSERTION(errorString, "unknown error, but don't alert user.");
-      if (errorString)
-      {
-        nsString errorMsg;
-        errorMsg.Adopt(FormatStringWithHostNameByName(errorString, msgUrl));
-        if (errorMsg.IsEmpty())
-        {
-          errorMsg.Assign(NS_LITERAL_STRING("[StringID "));
-          errorMsg.Append(errorString);
-          errorMsg.AppendLiteral("?]");
-        }
-
-        nsCOMPtr<nsIMsgMailSession> mailSession =
-          do_GetService(NS_MSGMAILSESSION_CONTRACTID, &rv);
-        NS_ENSURE_SUCCESS(rv, rv);
-
-        rv = mailSession->AlertUser(errorMsg, msgUrl);
-      }
-    } // if we got an error code
+      ShowAlertMessage(msgUrl, aStatus);
   } // if we have a mailnews url.
 
   // Drop notification callbacks to prevent cycles.
   mCallbacks = nullptr;
   mProgressEventSink = nullptr;
   // Call CloseSocket(), in case we got here because the server dropped the
   // connection while reading, and we never get a chance to get back into
   // the protocol state machine via OnDataAvailable.
--- a/mailnews/base/util/nsMsgProtocol.h
+++ b/mailnews/base/util/nsMsgProtocol.h
@@ -58,16 +58,17 @@ public:
 
   // LoadUrl -- A protocol typically overrides this function, sets up any local state for the url and
   // then calls the base class which opens the socket if it needs opened. If the socket is 
   // already opened then we just call ProcessProtocolState to start the churning process.
   // aConsumer is the consumer for the url. It can be null if this argument is not appropriate
   virtual nsresult LoadUrl(nsIURI * aURL, nsISupports * aConsumer = nullptr);
 
   virtual nsresult SetUrl(nsIURI * aURL); // sometimes we want to set the url before we load it
+  void ShowAlertMessage(nsIMsgMailNewsUrl *aMsgUrl, nsresult aStatus);
 
   // Flag manipulators
   virtual bool TestFlag  (uint32_t flag) {return flag & m_flags;}
   virtual void   SetFlag   (uint32_t flag) { m_flags |= flag; }
   virtual void   ClearFlag (uint32_t flag) { m_flags &= ~flag; }
 
 protected:
   virtual ~nsMsgProtocol();
--- a/mailnews/local/src/nsPop3Protocol.cpp
+++ b/mailnews/local/src/nsPop3Protocol.cpp
@@ -952,16 +952,18 @@ NS_IMETHODIMP nsPop3Protocol::OnTranspor
 NS_IMETHODIMP nsPop3Protocol::OnStopRequest(nsIRequest *aRequest, nsISupports * aContext, nsresult aStatus)
 {
   // If the server dropped the connection, m_socketIsOpen will be true, before
   // we call nsMsgProtocol::OnStopRequest. The call will force a close socket,
   // but we still want to go through the state machine one more time to cleanup
   // the protocol object.
   if (m_socketIsOpen)
   {
+    nsCOMPtr<nsIMsgMailNewsUrl> msgUrl = do_QueryInterface(m_url);
+
     // Check if the connection was dropped before getting back an auth error.
     // If we got the auth error, the next state would be
     // POP3_OBTAIN_PASSWORD_EARLY.
     if ((m_pop3ConData->next_state_after_response == POP3_NEXT_AUTH_STEP ||
          m_pop3ConData->next_state_after_response == POP3_AUTH_LOGIN_RESPONSE) &&
         m_pop3ConData->next_state != POP3_OBTAIN_PASSWORD_EARLY)
     {
       MOZ_LOG(POP3LOGMODULE, LogLevel::Debug, (POP3LOG("dropped connection before auth error")));
@@ -974,16 +976,20 @@ NS_IMETHODIMP nsPop3Protocol::OnStopRequ
     // We can't call nsMsgProtocol::OnStopRequest because it calls SetUrlState,
     // which notifies the URLListeners, but we need to do a bit of cleanup
     // before running the url again.
     CloseSocket();
     if (m_loadGroup)
       m_loadGroup->RemoveRequest(static_cast<nsIRequest *>(this), nullptr, aStatus);
     m_pop3ConData->next_state = POP3_ERROR_DONE;
     ProcessProtocolState(nullptr, nullptr, 0, 0);
+
+    if (NS_FAILED(aStatus))
+      nsMsgProtocol::ShowAlertMessage(msgUrl, aStatus);
+
     return NS_OK;
   }
   nsresult rv = nsMsgProtocol::OnStopRequest(aRequest, aContext, aStatus);
 
   // turn off the server busy flag on stop request - we know we're done, right?
   nsCOMPtr<nsIMsgIncomingServer> server = do_QueryInterface(m_pop3Server);
   if (server)
   {