Repository: expo/expo
File: apps/expo-go/android/expoview/src/main/java/host/exp/exponent/home/HomeAppViewModel.kt (Kotlin)

Code before:
    }
  )

  val feedbackState = MutableStateFlow(FeedbackState())

  private suspend fun checkDevelopmentServer(host: String, port: String): DevSession? {
    return withContext(Dispatchers.IO) {
      try {
        val request = Request.Builder().url("http://$host:$port/status").build()
        client.newCall(request).execute().use { response ->
          if (response.isSuccessful && response.body?.string()?.contains("packager-status:running") == true) {
            val manifestInfo = fetchLocalManifestInfo("http://$host:$port")
            return@withContext DevSession(
              url = "exp://$host:$port",
              description = manifestInfo?.extra?.expoClient?.name ?: "exp://$host:$port",
              source = DevSessionSource.Desktop,
              hostname = "exp://$host:$port",
              platform = DevSessionPlatform.Native,
              config = null,
              iconUrl = manifestInfo?.extra?.expoClient?.iconUrl
            )
          }
        }
      } catch (e: Exception) {
        // Ignore connection errors, server is likely not running on this port
      }
      null
    }
  }

  private suspend fun fetchLocalManifestInfo(baseUrl: String): ManifestResponse? {
    return withContext(Dispatchers.IO) {
      val manifestUrl = "$baseUrl/manifest"
      val request = Request.Builder()
        .url(manifestUrl)
        .addHeader("Accept", "application/expo+json,application/json")
        .addHeader("Expo-Platform", "android")
        .build()

      try {
        client.newCall(request).execute().use { response ->
          if (response.isSuccessful) {
            response.body?.string()?.let {
              return@withContext gson.fromJson(it, ManifestResponse::class.java)
            }
          }
        }
      } catch (e: Exception) {
        // Ignore errors
      }
      null

Review comment (suggestion):
Can u replace this try..catch with the runCatching function: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/run-catching.html

Code after:
  private val selectedAccountId = persistedMutableStateFlow(
    scope = viewModelScope,
    readValue = { sessionRepository.getSelectedAccountId() },
    writeValue = { value ->
      if (value == null) {
        sessionRepository.clearSelectedAccountId()
      } else {
        sessionRepository.saveSelectedAccountId(value)
      }
    }
  )

  val selectedTheme = persistedMutableStateFlow(
    scope = viewModelScope,
    readValue = { sessionRepository.getThemeSetting() },
    writeValue = { value ->
      sessionRepository.saveThemeSetting(value)
    }
  )

  val feedbackState = MutableStateFlow(FeedbackState())

  private suspend fun checkDevelopmentServer(host: String, port: String): DevSession? {
    return withContext(Dispatchers.IO) {
      runCatching {
        val url = "http://$host:$port"
        val request = Request.Builder().url("$url/status").build()
        val response = client.newCall(request).execute()

        if (!response.isSuccessful || response.body?.string()?.contains("packager-status:running") != true) {
          return@runCatching null
        }

        val manifestInfo = fetchLocalManifestInfo(url)
        DevSession(
          url = "exp://$host:$port",
          description = manifestInfo?.extra?.expoClient?.name ?: "exp://$host:$port",
          source = DevSessionSource.Desktop,
          hostname = "exp://$host:$port",
          platform = DevSessionPlatform.Native,
          config = null,
          iconUrl = manifestInfo?.extra?.expoClient?.iconUrl
        )
      }.getOrNull()
    }
  }

  private suspend fun fetchLocalManifestInfo(baseUrl: String): ManifestResponse? {
    return withContext(Dispatchers.IO) {
      runCatching {
        val manifestUrl = "$baseUrl/manifest"