Skip to content

FIS error handling #911

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 30 commits into from
Oct 16, 2019
Merged

FIS error handling #911

merged 30 commits into from
Oct 16, 2019

Conversation

ankitaj224
Copy link
Contributor

@ankitaj224 ankitaj224 commented Oct 14, 2019

For FirebaseInstallationServiceClient#createFirebaseInstallation

  1. 5xx errors, do not update the PersistedInstallationEntry status to REGISTER_ERROR
  2. Store detailed 4xx server exceptions in the local storage. In the succeeding getId calls, return the error message to the clients

* Fixing FISClient to correctly parse expiration timestamp.
* Updating getAuthToken to return creation timestamp along with auth token and
expiration timestamp.
* Propagating the exceptions to the clients.

* Adding javadocs for StateListener class.
* Addressing Rayo's comment: Rename PersistedFidEntry to (#899)
…errors

2. Store detailed 4xx server exceptions in the local storage. In the
succeeding getId calls,return these exceptions to the clients
@ankitaj224 ankitaj224 self-assigned this Oct 14, 2019
@googlebot googlebot added the cla: yes Override cla label Oct 14, 2019
@andirayo
Copy link
Contributor

Regarding the PR's description:
"""Incase of 500 errors, mark PersistedInstallationEntry status UNREGISTERED"""

I am confused by this sentence.
5XX errors are server-errors that the server usually recovers from after a retry.
I may be missing context, but usually the SDK should retry one time a request that it got a 5XX response for and then give up, but not change the status of the Installation.

@@ -291,6 +292,31 @@ public void testGetId_PersistedInstallationOk_BackendError() throws Exception {
assertThat(updatedInstallationEntry).hasRegistrationStatus(RegistrationStatus.REGISTER_ERROR);
}

@Test
public void testGetId_500ServerError_UnregisteredFID() throws Exception {
when(backendClientReturnsOk.createFirebaseInstallation(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where does this test stub a 500 error?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the confusion. Added a comment & changed the test name. Does this makes sense?

@@ -41,6 +41,9 @@

public abstract long getTokenCreationEpochInSecs();

@Nullable
public abstract String getFISException();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are we exposing this to clients? Having exception == String is weird. How about just calling it error message?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the stored error message. Changed it. PTAL.

Idea: getId is non-blocking call. After we return the id, we encounter some error during registration. We persist the error message & return it to the clients next time getId is called.

@@ -44,6 +44,7 @@ package com.google.firebase.installations.local {
method @NonNull public static com.google.firebase.installations.local.PersistedInstallationEntry.Builder builder();
method @Nullable public abstract String getAuthToken();
method public abstract long getExpiresInSecs();
method @Nullable public abstract String getFISException();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be #getFisException

Compare:
http://go/java-style#s5.3-camel-case

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.thanks.

.setExpiresInSecs(installationResponse.getAuthToken().getTokenExpirationTimestamp())
.setTokenCreationEpochInSecs(creationTime)
.build());
if (installationResponse.getFid() != null) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fyi:
If a #createInstallation request gets a successful response, the field "fid" should always be set.

What happens here if the field "fid" is not set? What state will the SDK end up in?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to differentiate between 200, 5xx & 4xx errors.

200 - createInstallation successful response - fid is not empty
5xx - retry once - empty response & fid
4xx - throws exception

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If that is what you are doing, then I would recommend your code to express that.
In this case, I would recommend that you check for the 200 HTTP-status instead of the "fid" field.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For that: I have to include Response Code as a field in InstallationResponse. Is that what you recommend?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since y'all control both sides of this exchange we should be able to use and trust the status codes. imo having canonical status codes as a classification for installation responses is a good idea.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack. PTAL.

@@ -90,6 +93,9 @@ public abstract Builder setRegistrationStatus(
@NonNull
public abstract Builder setTokenCreationEpochInSecs(long value);

@NonNull
public abstract Builder setFISException(@Nullable String value);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why can this be @nullable?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When PersistedInstallationEntry stores a successfully registered entry.

@@ -128,7 +128,8 @@ public InstallationResponse createFirebaseInstallation(
throw new FirebaseException(readErrorResponse(httpsURLConnection));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

referring to the 4 lines above:
case 500: retryCount++;

Is it possible for us to treat all server-errors (i.e. 5XX) like this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. PTAL.

@ankitaj224
Copy link
Contributor Author

Regarding the PR's description:
"""Incase of 500 errors, mark PersistedInstallationEntry status UNREGISTERED"""

I am confused by this sentence.
5XX errors are server-errors that the server usually recovers from after a retry.
I may be missing context, but usually the SDK should retry one time a request that it got a 5XX response for and then give up, but not change the status of the Installation.

Background:
My previous impl of FIS Android SDK would retry once on 500, then throw an exception. That would result in persisted installation entry status marked as REGISTER_ERROR.

After our discussion: On 5xx, we retry once & leave the persisted installation entry status as UNREGISTERED. As a result, no exception will be thrown on subsequent getId calls.

.setExpiresInSecs(installationResponse.getAuthToken().getTokenExpirationTimestamp())
.setTokenCreationEpochInSecs(creationTime)
.build());
if (installationResponse.getFid() != null) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If that is what you are doing, then I would recommend your code to express that.
In this case, I would recommend that you check for the 200 HTTP-status instead of the "fid" field.

@ankitaj224 ankitaj224 merged commit 42e442f into fis_sdk Oct 16, 2019
@ankitaj224 ankitaj224 deleted the fis-errors branch October 16, 2019 17:40
@firebase firebase locked and limited conversation to collaborators Nov 16, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
cla: yes Override cla size/L
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants