1 // Copyright 2015-present 650 Industries. All rights reserved.
2 package host.exp.exponent.exceptions
3 
4 import android.content.Context
5 import android.provider.Settings
6 import host.exp.exponent.kernel.ExponentErrorMessage
7 import host.exp.exponent.network.ExponentNetwork
8 import host.exp.expoview.Exponent
9 import java.lang.Exception
10 import java.net.ConnectException
11 import java.net.SocketTimeoutException
12 import java.net.UnknownHostException
13 
14 object ExceptionUtils {
15 
16   /**
17    * Converts an exception into and ExponentErrorMessage, which contains both a user facing
18    * error message and a developer facing error message.
19    * Example:
20    *  ManifestException with
21    *    manifestUrl="exp://exp.host/@exponent/pomodoro"
22    *    originalException=UnknownHostException
23    *
24    *    turns into:
25    *
26    *  ExponentErrorMessage with
27    *    userErrorMessage="Could not load exp://exp.host/@exponent/pomodoro. Airplane mode is on."
28    *    developerErrorMessage="java.net.UnknownHostException: Unable to resolve host"
29    **/
exceptionToErrorMessagenull30   fun exceptionToErrorMessage(exception: Exception): ExponentErrorMessage {
31     val context: Context = Exponent.instance.application
32     val defaultResponse = ExponentErrorMessage.developerErrorMessage(exception.toString())
33 
34     if (exception is ExponentException) {
35       // Grab both the user facing message from ExponentException
36       var message = exception.toString()
37 
38       // Append general exception error messages if applicable
39       if (exception.originalException() != null) {
40         val userErrorMessage = getUserErrorMessage(exception.originalException(), context)
41         if (userErrorMessage != null) {
42           message += " $userErrorMessage"
43         }
44       }
45 
46       return ExponentErrorMessage(message, exception.originalExceptionMessage())
47     }
48 
49     val userErrorMessage = getUserErrorMessage(exception, context)
50     return if (userErrorMessage != null) {
51       defaultResponse.addUserErrorMessage(userErrorMessage)
52     } else {
53       defaultResponse
54     }
55   }
56 
exceptionToErrorHeadernull57   fun exceptionToErrorHeader(exception: Exception): String? {
58     if (exception is ManifestException) {
59       return exception.errorHeader
60     }
61     return null
62   }
63 
getUserErrorMessagenull64   private fun getUserErrorMessage(exception: Exception?, context: Context): String? {
65     if (exception is UnknownHostException || exception is ConnectException) {
66       if (isAirplaneModeOn(context)) {
67         return "Airplane mode is on. Please turn off and try again."
68       } else if (!ExponentNetwork.isNetworkAvailable(context)) {
69         return "Can't connect to internet. Please try again."
70       }
71     } else if (exception is SocketTimeoutException) {
72       return "Network response timed out."
73     }
74     return null
75   }
76 
isAirplaneModeOnnull77   private fun isAirplaneModeOn(context: Context): Boolean {
78     return Settings.System.getInt(context.contentResolver, Settings.Global.AIRPLANE_MODE_ON, 0) != 0
79   }
80 }
81