Docs Menu

Docs HomeDevelop ApplicationsAtlas Device SDKs

Handle App Errors - Kotlin SDK

On this page

  • Service Errors
  • Connection Errors
  • Bad Request Errors
  • Auth Errors
  • Example

App errors fall into two major categories:

  • service errors occur when an Atlas App Services request fails at the HTTP level. These errors generate a ServiceException

  • sync errors occur when Device Sync fails. These errors generate a SyncException. For more information on sync exceptions, refer to Handle Sync Errors.

However, some errors are ephemeral: they occur because of failures outside of the client or SDK's control. For example, a failed login attempt due to a network error.

Other errors require logic fixes. For example, a failed login attempt due to incorrect credentials.

When an ephemeral error occurs, you should retry the operation that caused the error. If the operation still fails when you retry it, investigate logic fixes.

A ServiceException occurs when an Atlas App Services request fails at the HTTP level, i.e. the HTTP request returned, but the HTTP Status code was not 200 (OK).

A ConnectionException occurs when HTTP communication fails between the SDK and the App Services backend, ie. the HTTP request isn't able to receive a status code.

Because these errors stem from network layers outside of the SDK's control, you should consider these errors ephemeral. Retry the operation, then investigate the error if the retry fails. If the operation fails because the client device is offline, you can ask the app user to retry the operation when they reconnect to the internet.

A BadRequestException occurs from malformed App Services requests.

When you get a bad request error:

  • Check the inputs for the operation.

  • Check your App logs for more information about what went wrong.

An AuthException occurs when a user account action, such as login, logout, or registration, fails. Usually, you'll get a more specific subtype that helps you identify a solution.

A UserAlreadyConfirmedException occurs when you attempt to confirm a user who you have already confirmed.

When you get a user already confirmed error, it's best to not disrupt the application flow. Since the user is confirmed, you can safely proceed to log in. There is no need to retry confirmation.

A UserNotFoundException occurs when the App Services backend cannot find a user with the supplied username. This is commonly caused by typos in email/password usernames.

When you experience this error, prompt the user to re-enter their username and try again.

A UserAlreadyExistsException occurs when a client attempts to register a user with a username that is already in use in that App.

When you experience this error, prompt users to:

  • use a different username

  • login with their existing username if they already have an account

An InvalidCredentialsException occurs when a JWT, email/password, or API Key user login fails due to invalid credentials. Other authentication providers throw an Auth Error instead.

You can handle errors in the SDK with Kotlin's built-in runCatching API. Use the onSuccess and onFailure callbacks of the returned Result to handle successful SDK API calls and error cases. The following example logs an anonymous user into an App. If the login attempt succeeds, we log the successful authentication attempt and transition the user to another screen. If the login attempt fails, we handle each potential error case individually:

  • If the user supplied invalid credentials, we log the attempt and display a popup toast encouraging the user to check their credentials.

  • If there was a problem with the network connection, we log the problem to the error log and display a popup toast encouraging the user to check their network connection and try again.

  • For all other errors, we log the problem to the error log and display a popup toast informing the user that the login attempt failed.

val app = App.create(YOUR_APP_ID)
runCatching {
app.login(Credentials.emailPassword(email, password))
}.onSuccess {
Log.v("Successfully logged in")
// transition to another activity, load a fragment, to display logged-in user information here
}.onFailure { ex: Throwable ->
when (ex) {
is InvalidCredentialsException -> {
Log.v("Failed to login due to invalid credentials: ${ex.message}")
Toast.makeText(baseContext,
"Invalid username or password. Please try again.", Toast.LENGTH_LONG).show()
}
is ConnectionException -> {
Log.e("Failed to login due to a connection error: ${ex.message}")
Toast.makeText(baseContext,
"Login failed due to a connection error. Check your network connection and try again.", Toast.LENGTH_LONG).show()
}
else -> {
Log.e("Failed to login: ${ex.message}")
// generic error message for niche and unknown fail cases
Toast.makeText(baseContext,
"Login failed. Please try again.", Toast.LENGTH_LONG).show()
}
}
}
← Call an Atlas Function - Kotlin SDK