Skip to content

Commit

Permalink
Added try catch blocks in Network requests to prevent timeout issues …
Browse files Browse the repository at this point in the history
…from crashing the app
  • Loading branch information
baronhsieh2005 committed Aug 23, 2024
1 parent 8895a21 commit d26434e
Show file tree
Hide file tree
Showing 23 changed files with 1,232 additions and 772 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -142,49 +142,53 @@ class BookGsrFragment : Fragment() {
Log.i("BookGSRFragment", "ID $roomId")
Log.i("BookGSRFragment", "Room Name $roomName")

mStudentLife.bookGSR(
// Passing the values
bearerToken,
startTime,
endTime,
gid,
roomId,
roomName,
// Creating an anonymous callback
object : Callback<GSRBookingResult> {
override fun success(
result: GSRBookingResult,
response: Response,
) {
// Displaying the output as a toast and go back to GSR fragment
if (result.getDetail().equals("success")) {
Toast.makeText(activity, "GSR successfully booked", Toast.LENGTH_LONG).show()

// Save user info in shared preferences
val sp = PreferenceManager.getDefaultSharedPreferences(activity)
val editor = sp.edit()
editor.putString(getString(R.string.first_name), firstNameEt.text.toString())
editor.putString(getString(R.string.last_name), lastNameEt.text.toString())
editor.putString(getString(R.string.email_address), emailEt.text.toString())
editor.apply()
} else {
Toast.makeText(activity, "GSR booking failed", Toast.LENGTH_LONG).show()
Log.e("BookGsrFragment", "GSR booking failed with " + result.getError())
try {
mStudentLife.bookGSR(
// Passing the values
bearerToken,
startTime,
endTime,
gid,
roomId,
roomName,
// Creating an anonymous callback
object : Callback<GSRBookingResult> {
override fun success(
result: GSRBookingResult,
response: Response,
) {
// Displaying the output as a toast and go back to GSR fragment
if (result.getDetail().equals("success")) {
Toast.makeText(activity, "GSR successfully booked", Toast.LENGTH_LONG).show()

// Save user info in shared preferences
val sp = PreferenceManager.getDefaultSharedPreferences(activity)
val editor = sp.edit()
editor.putString(getString(R.string.first_name), firstNameEt.text.toString())
editor.putString(getString(R.string.last_name), lastNameEt.text.toString())
editor.putString(getString(R.string.email_address), emailEt.text.toString())
editor.apply()
} else {
Toast.makeText(activity, "GSR booking failed", Toast.LENGTH_LONG).show()
Log.e("BookGsrFragment", "GSR booking failed with " + result.getError())
}
// go back to GSR fragment
binding.loading.loadingPanel.visibility = View.GONE
activity?.onBackPressed()
}
// go back to GSR fragment
binding.loading.loadingPanel.visibility = View.GONE
activity?.onBackPressed()
}

override fun failure(error: RetrofitError) {
// If any error occurred displaying the error as toast
Log.e("BookGSRFragment", "Error booking gsr", error)
Toast.makeText(activity, "An error has occurred. Please try again.", Toast.LENGTH_LONG).show()
binding.loading.loadingPanel.visibility = View.GONE
activity?.onBackPressed()
}
},
)

override fun failure(error: RetrofitError) {
// If any error occurred displaying the error as toast
Log.e("BookGSRFragment", "Error booking gsr", error)
Toast.makeText(activity, "An error has occurred. Please try again.", Toast.LENGTH_LONG).show()
binding.loading.loadingPanel.visibility = View.GONE
activity?.onBackPressed()
}
},
)
} catch (e: Exception) {
e.printStackTrace()
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,42 +153,46 @@ class DiningFragment : Fragment() {
}

// Map each item in the list of venues to a Venue Observable, then map each Venue to a DiningHall Observable
mStudentLife.venues()
.flatMap { venues -> Observable.from(venues) }
.flatMap { venue ->
val hall = createHall(venue)
Observable.just(hall)
}
.toList()
.subscribe({ diningHalls ->
mActivity.runOnUiThread {
getMenus(diningHalls)
val adapter = DiningAdapter(diningHalls)
loadingPanel?.visibility = View.GONE
if (diningHalls.size > 0) {
no_results?.visibility = View.GONE
try {
mStudentLife.venues()
.flatMap { venues -> Observable.from(venues) }
.flatMap { venue ->
val hall = createHall(venue)
Observable.just(hall)
}
.toList()
.subscribe({ diningHalls ->
mActivity.runOnUiThread {
getMenus(diningHalls)
val adapter = DiningAdapter(diningHalls)
loadingPanel?.visibility = View.GONE
if (diningHalls.size > 0) {
no_results?.visibility = View.GONE
}

// Log non-fatal error to crashyltics if null
// this error should not really be happening
// it is *possible* but be rare: ideally network stuff
// is decoupled with UI updates
try {
binding.diningHallsRecyclerView.adapter = adapter
binding.diningSwiperefresh.isRefreshing = false
} catch (e: Exception) {
FirebaseCrashlytics.getInstance().recordException(e)
}
view?.let { displaySnack("Just Updated") }
}

// Log non-fatal error to crashyltics if null
// this error should not really be happening
// it is *possible* but be rare: ideally network stuff
// is decoupled with UI updates
try {
binding.diningHallsRecyclerView.adapter = adapter
}, {
Log.e("DiningFragment", "Error getting dining halls", it)
mActivity.runOnUiThread {
Log.e("Dining", "Could not load Dining page", it)
loadingPanel?.visibility = View.GONE
binding.diningSwiperefresh.isRefreshing = false
} catch (e: Exception) {
FirebaseCrashlytics.getInstance().recordException(e)
}
view?.let { displaySnack("Just Updated") }
}
}, {
Log.e("DiningFragment", "Error getting dining halls", it)
mActivity.runOnUiThread {
Log.e("Dining", "Could not load Dining page", it)
loadingPanel?.visibility = View.GONE
binding.diningSwiperefresh.isRefreshing = false
}
})
})
} catch (e: Exception) {
e.printStackTrace()
}
}

override fun onResume() {
Expand Down Expand Up @@ -221,23 +225,27 @@ class DiningFragment : Fragment() {
companion object {
// Gets the dining hall menus
fun getMenus(venues: MutableList<DiningHall>) {
val idVenueMap = mutableMapOf<Int, DiningHall>()
venues.forEach { idVenueMap[it.id] = it }
val current = LocalDateTime.now()
val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
val formatted = current.format(formatter)
val studentLife = MainActivity.studentLifeInstance
studentLife.getMenus(formatted).subscribe({ menus ->
menus.forEach { menu ->
val id = menu.venue?.venueId
val diningHall = idVenueMap[id]
val diningHallMenus = diningHall?.menus ?: mutableListOf()
diningHallMenus.add(menu)
diningHall?.sortMeals(diningHallMenus)
}
}, { throwable ->
Log.e("DiningFragment", "Error getting Menus", throwable)
})
try {
val idVenueMap = mutableMapOf<Int, DiningHall>()
venues.forEach { idVenueMap[it.id] = it }
val current = LocalDateTime.now()
val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
val formatted = current.format(formatter)
val studentLife = MainActivity.studentLifeInstance
studentLife.getMenus(formatted).subscribe({ menus ->
menus.forEach { menu ->
val id = menu.venue?.venueId
val diningHall = idVenueMap[id]
val diningHallMenus = diningHall?.menus ?: mutableListOf()
diningHallMenus.add(menu)
diningHall?.sortMeals(diningHallMenus)
}
}, { throwable ->
Log.e("DiningFragment", "Error getting Menus", throwable)
})
} catch (e: Exception) {
e.printStackTrace()
}
}

// Takes a venue then adds an image and modifies venue name if name is too long
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package com.pennapps.labs.pennmobile

import android.app.PendingIntent
import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetProvider
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.widget.RemoteViews
import com.google.gson.GsonBuilder
import com.google.gson.reflect.TypeToken
import com.pennapps.labs.pennmobile.adapters.DiningHallWidgetAdapter
import com.pennapps.labs.pennmobile.api.DiningRequest
import com.pennapps.labs.pennmobile.api.Serializer
import com.pennapps.labs.pennmobile.classes.Venue
import com.squareup.okhttp.OkHttpClient
import retrofit.RestAdapter
import retrofit.client.OkClient
import retrofit.converter.GsonConverter
import java.util.concurrent.TimeUnit

class DiningHallListWidget : AppWidgetProvider() {
override fun onUpdate(
context: Context?,
appWidgetManager: AppWidgetManager?,
appWidgetIds: IntArray?
) {
super.onUpdate(context, appWidgetManager, appWidgetIds)
}

override fun onEnabled(context: Context?) {
super.onEnabled(context)
}

override fun onDisabled(context: Context?) {
super.onDisabled(context)
}

companion object {
private var mDiningRequest : DiningRequest? = null;
val ACTION_AUTO_UPDATE = "AUTO_UPDATE"

@JvmStatic
val diningRequestInstance : DiningRequest
get() {
if (mDiningRequest == null) {
val gsonBuilder = GsonBuilder()

gsonBuilder.registerTypeAdapter(
object : TypeToken<MutableList<Venue?>?>() {}.type,
Serializer.VenueSerializer()
)

val gson = gsonBuilder.create()
val okHttpClient = OkHttpClient()
okHttpClient.setConnectTimeout(35, TimeUnit.SECONDS)
okHttpClient.setReadTimeout(35, TimeUnit.SECONDS)
okHttpClient.setWriteTimeout(35, TimeUnit.SECONDS)

val restAdapter =
RestAdapter.Builder()
.setConverter(GsonConverter(gson))
.setClient(OkClient(okHttpClient))
.setEndpoint("https://pennmobile.org/api")
.build()
mDiningRequest = restAdapter.create(DiningRequest::class.java)
}
return mDiningRequest!!
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -92,25 +92,30 @@ class DiningSettingsFragment(dataModel: HomepageDataModel) : Fragment() {
private fun getDiningHalls() {
// Map each item in the list of venues to a Venue Observable, then map each Venue to a DiningHall Observable
originalPreferences = dataModel.getDiningHallPrefs()
mStudentLife.venues()
.flatMap { venues -> Observable.from(venues) }
.flatMap { venue ->
val hall = DiningFragment.createHall(venue)
Observable.just(hall)
}
.toList()
.subscribe({ diningHalls ->
mActivity.runOnUiThread {
halls = diningHalls
try {
binding.diningHallRv.adapter = DiningSettingsAdapter(diningHalls)
} catch (e: Exception) {
FirebaseCrashlytics.getInstance().recordException(e)
}
try {
mStudentLife.venues()
.flatMap { venues -> Observable.from(venues) }
.flatMap { venue ->
val hall = DiningFragment.createHall(venue)
Observable.just(hall)
}
}, {
Log.e("DiningSettings", "error fetching dining halls")
})
.toList()
.subscribe({ diningHalls ->
mActivity.runOnUiThread {
halls = diningHalls
try {
binding.diningHallRv.adapter = DiningSettingsAdapter(diningHalls)
} catch (e: Exception) {
FirebaseCrashlytics.getInstance().recordException(e)
}
}
}, {
Log.e("DiningSettings", "error fetching dining halls")
})
} catch (e: Exception) {
e.printStackTrace()
}

}

override fun onDestroyView() {
Expand Down Expand Up @@ -146,25 +151,29 @@ class DiningSettingsFragment(dataModel: HomepageDataModel) : Fragment() {
mActivity.mNetworkManager.getAccessToken {
val bearerToken =
"Bearer " + sp.getString(getString(R.string.access_token), "").toString()
mStudentLife.sendDiningPref(
bearerToken,
DiningRequest(favoriteDiningHalls),
object : ResponseCallback() {
override fun success(response: Response) {
Log.i("Dining", "Dining preferences saved")
mActivity.onBackPressed()
}

override fun failure(error: RetrofitError) {
Log.e("Dining", "Error saving dining preferences: $error")
Toast.makeText(
mActivity,
"Error saving dining preferences",
Toast.LENGTH_SHORT,
).show()
}
},
)
try {
mStudentLife.sendDiningPref(
bearerToken,
DiningRequest(favoriteDiningHalls),
object : ResponseCallback() {
override fun success(response: Response) {
Log.i("Dining", "Dining preferences saved")
mActivity.onBackPressed()
}

override fun failure(error: RetrofitError) {
Log.e("Dining", "Error saving dining preferences: $error")
Toast.makeText(
mActivity,
"Error saving dining preferences",
Toast.LENGTH_SHORT,
).show()
}
},
)
} catch (e : Exception) {
e.printStackTrace()
}
}
}
}
Loading

0 comments on commit d26434e

Please sign in to comment.