JavaPNS error handling - contradiction in the docu

2019-08-30 01:22发布

问题:

In the JavaPNS docs, I see this:

To find out if a push was successfully sent to Apple and that Apple did not return any error-response packet, simply invoke the pushedNotification.isSuccessful() method. A notification might not be successful if any of these conditions occur:

  • the library rejected the token you provided because of obvious specs violations (ex: token not 64-bytes long, etc.)
  • the library rejected the payload you provided because of obvious specs violations (ex: payload too large, etc.)
  • a connection error occurred and the library was not able to communicate with Apple servers
  • an error occurred with your certificate or keystore (ex: wrong password, invalid keystore format, etc.)
  • a valid error-response packet was received from Apple servers

and many other possible errors...

But the code snippet provided then does

for (PushedNotification notification : notifications) {
    if (notification.isSuccessful()) {
        /* Apple accepted the notification and should deliver it */  
        System.out.println("Push notification sent successfully to: " + notification.getDevice().getToken());
    /* Still need to query the Feedback Service regularly */  
    } else {
        String invalidToken = notification.getDevice().getToken();
        /* Add code here to remove invalidToken from your database */  

        /* Find out more about what the problem was */  
        Exception theProblem = notification.getException();
        theProblem.printStackTrace();

        /* If the problem was an error-response packet returned by Apple, get it */  
        ResponsePacket theErrorResponse = notification.getResponse();
        if (theErrorResponse != null) {
            System.out.println(theErrorResponse.getMessage());
        }
     }
 }

Which seems to imply that isSuccess() == false means an unrecoverable error, and that the device token is not valid.

However, the list of possible reasons did say that isSUccess() might be false due to a legitimate error packet being returned. I don't know, but I imagine one might be returned if Apple failed to send the notification due carrier issues, for example, which means the token is not necessarily invalid.

Is the correct way to read this, then, that isSuccess() == false is an unrecoverable error when sending a message, but not one that requires an exception, like a keystore fail or an inability to connect to the servers at all?

In other words - id isSuccessful() == false, should I really delete the device token from my DB as suggested? The snippet says yes, but the documentation seems to me to suggest otherwise...

Links: http://code.google.com/p/javapns/wiki/ManagingPushErrors

Thanks in advance to anyone who has braved this long, rambling question.

-- Snorkel

回答1:

The documentation says that you are correct. Technically it means the push failed, but not that it failed because of an exception. It could have failed because of a legitimate failure. (I define legitimate failure as we successfully connected, there were no obvious defects with the message, but the server declined to accept it.) The key line is the following:

IE To find out if a push was successfully sent to Apple and that Apple did not return any error-response packet, simply invoke the pushedNotification.isSuccessful() method.

Your whole question seems pretty roundabout though. In a simple sense, your push failed. Does the distinction between an exception and a failure really matter? Either way its unrecoverable and you need to check the logs to see exactly what happened.