Search code examples
javaandroidexceptionnestedjakarta-mail

Android JavaMail API - Want to catch UnknownHostException


I use the Android JavaMail-API to send E-Mails. Everything works as intended, but right now I'm testing some things when I have a bad internet connection. I do this by disabling WIFI and then click on the Send E-mail Button.

In my SendMail-method I have the following:

try{
    if(javaMailAPI.send()){
        // Do something on success
    }
    else{
        // Do something on fail
    }
}
catch(UnknownHostException ex){
    // Do something when I have no Internet Connection
}
catch(Exception ex){
    // Do something else when I have an other Exception
}

So, when I test this above when I have my WIFI disconnected, this is what I expect:

  • UnknownHostException is catched because we have no Internet Connection, code inside that catch is used.

What is the result instead:

  • Exception is catched with the following error Stacktrace:

07-02 15:00:47.699: W/System.err(6680): javax.mail.MessagingException: Unknown SMTP host: smtp.gmail.com; 07-02 15:00:47.699: W/System.err(6680): nested exception is: 07-02 15:00:47.699: W/System.err(6680): java.net.UnknownHostException: Host is unresolved: smtp.gmail.com 07-02 15:00:47.699: W/System.err(6680): at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1389) 07-02 15:00:47.709: W/System.err(6680): at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:412) 07-02 15:00:47.709: W/System.err(6680): at javax.mail.Service.connect(Service.java:310) 07-02 15:00:47.709: W/System.err(6680): at javax.mail.Service.connect(Service.java:169) 07-02 15:00:47.709: W/System.err(6680): at javax.mail.Service.connect(Service.java:118) 07-02 15:00:47.709: W/System.err(6680): at javax.mail.Transport.send0(Transport.java:188) 07-02 15:00:47.709: W/System.err(6680): at javax.mail.Transport.send(Transport.java:118) 07-02 15:00:47.719: W/System.err(6680): at external_software.JavaMailAPI.send(JavaMailAPI.java:118) 07-02 15:00:47.719: W/System.err(6680): at controllers.EMailSender.SendEmails(EMailSender.java:58) 07-02 15:00:47.719: W/System.err(6680): at activities.ChecklistResultActivity$3.run(ChecklistResultActivity.java:300) 07-02 15:00:47.719: W/System.err(6680): at java.lang.Thread.run(Thread.java:841) 07-02 15:00:47.719: W/System.err(6680): Caused by: java.net.UnknownHostException: Host is unresolved: smtp.gmail.com 07-02 15:00:47.729: W/System.err(6680): at java.net.Socket.connect(Socket.java:826) 07-02 15:00:47.729: W/System.err(6680): at java.net.Socket.connect(Socket.java:786) 07-02 15:00:47.729: W/System.err(6680): at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:233) 07-02 15:00:47.729: W/System.err(6680): at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:163) 07-02 15:00:47.729: W/System.err(6680): at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1359) 07-02 15:00:47.729: W/System.err(6680): ... 10 more

And the code inside the other catch is used.

As you can see it catches the JavaMail-API's MessagingException, which is nesting the UnknownHostException.

So, how can I catch UnknownHostException / MessagingException that is nesting UnknownHostException? Is it possible to somehow retrieve the nested Exception?

Should I use this (source):

...
catch(Exception ex){
    if(ex.getCause() != null && ex.getCause().getCause() instanceof UnknownHostException){
        throw new UnknownHostException(ex.getMessage());
    }
    else{
        // Do something else when I have an other Exception
    }
}

PS: When I throw the UnknownHostException like above, will this go to the UnknownHostException above this catched Exception?


Solution

  • I've changed this:

    try{
        if(javaMailAPI.send()){
            // Do something on success
        }
        else{
            // Do something on fail
        }
    }
    catch(UnknownHostException ex){
        // Do something when I have no Internet Connection
    }
    catch(Exception ex){
        // Do something else when I have an other Exception
    }
    

    to this:

    try{
        if(javaMailAPI.send()){
            // Do something on success
        }
        else{
            // Do something on fail
        }
    }
    catch(UnknownHostException ex){
        onNoConnection();
    }
    catch(Exception ex){
        // Check if the thrown Exception is a MessagingException with a nested UnknownHostException
        if(ex instanceof MessagingException){
            if(((MessagingException)ex).getNextException() instanceof UnknownHostException){
                onNoConnection();
            }
        }
        else{
            // Do something else when I have an other Exception
        }
    }
    
    private void onNoConnection(){
        // Do something when I have no Internet Connection
    }
    

    And it works as intended.