Exception Handling
Some APIs in Kii Cloud SDK throw exceptions. In this section, we explain how you can handle the exceptions and how you can investigate the cause of the failure.
- Sample code in the guides
- Types of exceptions
- Error details
- Common API errors
- Tools for investigating errors
Sample code in the guides
In the guides, we provide sample code to illustrate how you can leverage our SDKs. In the sample code, the exception handling is usually simplified; the message output and error recovery are omitted.
For example, we present the following sample code when we explain how to register new users:
Blocking API
When an error occurs in a blocking API call, an exception will be thrown. You can handle the exception with a try/catch block just like any other Java programs. The sample code presented in the guides basically handle only abstract-level exceptions.
try {
user.register(password);
} catch (IOException e) {
// Handle the error.
return;
} catch (AppException e) {
// Handle the error.
return;
}
Non-Blocking API
When an error occurs in a non-blocking API call, an exception object will be passed as a parameter of a callback method. If there is no error, this exception object will be null.
user.register(new KiiUserCallBack() {
@Override
public void onRegisterCompleted(int token, KiiUser user, Exception exception) {
if (exception != null) {
// Handle the error.
return;
}
}
}, password);
Types of exceptions
In general, your application needs to handle the following two types of exceptions (unless the sample code says otherwise).
java.lang.IOException
IOException occurs when you call an API that accesses the network, but there are some issues in the networking with the server. Most of the time, this error is due to the unstable or misconfigured network.
-
AppException is the root exception in the exception class hierarchy (there is CloudException that is a superclass of AppException, but this is merely for the future extension). Usually, you will just need to catch AppException, as presented in the sample code.
When an API execution causes an error, Kii Android SDK will basically throw an exception object that is a subclass of AppException. If the API internally executes the REST API, it will throw the subclass exception that corresponds to the HTTP status returned by Kii Cloud as shown in the next table (if the HTTP status not listed in the table is returned, UndefinedException will be thrown).
HTTP Status Type of Exception 400 BadRequestException 401 UnauthorizedException 403 ForbiddenException 404 NotFoundException 409 ConflictException
These exceptions have the following hierarchy, so you can handle all of them by catching IOException and AppException in a try/catch block. For the complete list of all exceptions thrown by the SDK and the detailed explanation of the exceptions thrown by each API, please read the Javadoc.
You need to validate the string (i.e. its length and the characters in the string) before you pass it to the API as a parameter. The client SDK will check the parameter and throw RuntimeException (e.g. java.lang.IllegalArgumentException) if the parameter is invalid. If you are using a blocking API, this will cause your application to crash. Please note that some non-blocking API also throws RuntimeException when the parameter is invalid. There is BadRequestException defined as a subclass of AppException, but this will not cover the parameter error cases that are handled by IllegalArgumentException.
If you want to handle exceptions more precisely, you can check and handle individual exceptions as shown in the following sample code:
Blocking API
try {
user.register(password);
} catch (ConflictException e) {
// Registration failed because the user already exists.
return;
} catch (AppException e) {
// Registration failed because of another exception in the app layer.
return;
} catch (IOException e) {
// Registration failed because of an exception in the network layer.
return;
}
Non-Blocking API
user.register(new KiiUserCallBack() {
@Override
public void onRegisterCompleted(int token, KiiUser user, Exception exception) {
if (exception instanceof ConflictException) {
// Registration failed because the user already exists.
return;
} else if (exception instanceof AppException) {
// Registration failed because of another exception in the app layer.
return;
} else if (exception instanceof IOException) {
// Registration failed because of an exception in the network layer.
return;
} else if (exception != null) {
// Registration failed because of one of the other exceptions.
return;
}
}
}, password);
It is difficult to cover all exceptions and error cases thrown by each API. We recommend you to catch only specific cases that you need to handle explicitly (e.g. user duplication and network error) and handle other cases as a general error. Please note that exceptions and error codes can be added and modified as we update the SDK and server.
Error details
Sometimes you can get the details of the exception from AppException and its subclasses. The client SDK connects to Kii Cloud server via REST API. When the server returns an error, you can get the information returned by the server using the methods in the exception. The information is useful for determining the root cause of the error during your development.
For example, suppose that you try to register a user user_123456
but this user already exists in Kii Cloud. Executing the following code will cause a user duplication error. The sample code shows the error details you can get in this situation.
try {
KiiUser user = KiiUser.builderWithName("user_123456").build();
user.register(password);
} catch (ConflictException e) {
// Handle the error.
// Print the cause of the error.
System.out.println("-- getReason");
System.out.println(e.getReason());
// Print the error message.
System.out.println("-- getMessage");
System.out.println(e.getMessage());
return;
} catch (AppException e) {
// Handle the error.
return;
} catch (IOException e) {
// Handle the error.
return;
}
-- getReason
USER_ALREADY_EXISTS
-- getMessage
Error: null
HTTP Response Status: 409
HTTP Response Body: {
"errorCode" : "USER_ALREADY_EXISTS",
"message" : "User with loginName user_123456 already exists",
"value" : "user_123456",
"field" : "loginName"
}
This example shows the result of the user duplication. The error information obtainable differs by the situation. In your code, please make sure to handle the case when null is returned. For example, all REST API related details will be null if the error is raised solely by the client SDK inside).
getReason
methodThis method returns the enum that explains the reason of failure. The enum is available when the REST API is called inside the client SDK. The method is available on the following exception classes: BadRequestException, NotFoundException, and ConflictException.
getMessage
methodThis method returns the error details for debugging purposes. The return message includes the result of the
getBody
method, but it does not include the stack trace. If you just want to get the stack trace, you can use theprintStackTrace
method.If you encounter an unknown error while developing, you might get the error details by reading the
message
field of the HTTP Response BODY. In the above example, you can see that the specified user already exists in Kii Cloud.
There are more methods for getting the error details, but basically you should be able to investigate the problem with the exception type and the result of the getReason
method.
When you are going to ask for some help, we encourage you to provide this information as the reference.
For more details on errors, please check AppException class reference, including its superclass and subclasses.
If you want to control your Android code based on the error reason, we recommend coding your application as follows:
Check the exception type. For example, you can learn that the user duplication occurs when
ConflictException
is thrown.If you cannot determine the error reason by the exception type (e.g. the same exception will be thrown in multiple situations), check the details with the
getReason
method and take the appropriate action.
Common API errors
There are common API errors for cases including when refresh of an access token fails and when the server receives too many requests.
Failed refresh of access tokens
If you are going to leverage the refresh token feature, we encourage you to design your application so as to handle the RefreshTokenFailedException
case.
As explained in this section, you need to execute relogin with a username and password when you get the RefreshTokenFailedException
exception; therefore, your application needs to show the initial screen or the login screen so as to ask for user relogin. This check needs to be made for all API calls that access the network, so it is essential to design how to handle such a situation beforehand.
Too many requests
The API returns error if there are accesses that greatly exceed the ordinary load to the server within a certain period of time for an application. This limit is set per application under an agreement with Kii.
The limit is high enough for ordinary changes in the operational load. However, if active users simultaneously send a request on the same time or event, it could cause an API error.
If the number of API calls exceeds the limit, each API returns error with the UndefinedException
class that is a subclass of the AppException
class. The getStatus()
method of the UndefinedException
instance returns error code 429. Detailed information is not available because the UndefinedException
class does not have the getReason()
method.
Usually, a mobile app processes this error as an unexpected error on the server. To avoid congestion, do not implement a retry process for executing the API.
Tools for investigating errors
There are a couple of tools available to help you investigate the error root cause.
Developer log
The error details are recorded in the developer log.
See Inspect Developer Log to learn how you can inspect the error log to spot the root cause while developing and troubleshooting.
The following log is a sample of logs that are recorded when the user duplication occurs:
2015-04-21T11:45:11.783+09:00 [ERROR] user.register description:User registration failed userID: login-name:user_123456 email-address:user_123456@example.com phone-number:+819012345678 exception:User with loginName user_123456 already exists
Data browser
You can verify if the data updated in your application are properly set in Kii Cloud.
See Checking and Updating Data, Users, and Groups for more details.