Kotlin error when fetching API with RxJava - kotlin

So I'm new to kotlin, and I'm trying to fetch API with RxJava by following this tutorial https://www.youtube.com/watch?v=VObSnk5jrpc&list=PLRRNzqzbPLd906bPH-xFz9Oy2IcjqVWCH&index=6
But I got an error saying:
Type mismatch: inferred type is String? but String was expected
Here is the code:
try {
compositeDisposable.add(
apiService.getMovieDetails(movieId)
.subscribeOn(Schedulers.io())
.subscribe(
{
_downloadedMovieDetailsResponse.postValue(it)
_networkState.postValue(NetworkState.LOADED)
},
{
_networkState.postValue(NetworkState.ERROR)
Log.e("MovieDetailsDataSource", it.message) //this is where the error is (the it.message)
}
)
)
}
catch (e: Exception){
Log.e("MovieDetailsDataSource",e.message) //this is where the error is (the e.message)
}
How to solve this?

Simply put
e.message!!
The Problem will be solved

Related

Type mismatch on throw line in Kotlin?

Please help me understand the following error in Kotlin: I have the following function
fun getSomething(): Something {
return loginContext.user()?.let {
// user is logged in
return Something()
} ?: {
// user is not logged in
throw UnauthorizedException()
}
}
and IntelliJ tells me
Type mismatch.
Required: Something
Found: () → Nothing
Coming from Java I find this a bit confusing because when I throw an exception there is nothing to return. How can there be a type mismatch?
I believe you may write it like this (using expression body)
fun getSomething(): Something = loginContext.user()
?.let { Something() }
?: throw UnauthorizedException()

Spring Webflux: Return statuscode and message based on exception thrown

How to determine which exception is thrown and get the status code out of it in Spring Webflux.
This is the structure of my controller code.
#GetMapping("/")
fun getResults() : Mono<ResponseEntity<AccountDTO>>{
return Service.getResult()
.map {
}.doOnError {
//how to get statuscode here
throw ResponseStatusException(HttpStatus.NOT_FOUND, it.message!!)
}
Here I can get the custom message thrown, but how to get the status code? Instead of HttpStatus.NOT_FOUND. I want to capture the status code that is thrown by the service layer. Or is there a way to get the exception thrown?
I found a solution that works.
#GetMapping("/")
fun getResults() : Mono<ResponseEntity<AccountDTO>>{
return Service.getResult()
.map {
}.doOnError {
if(it is NotFoundException)
{
throw ResponseStatusException(HttpStatus.NOT_FOUND)
}
else{
throw ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR)
}
}

Functional (Result / Error) translation using Kotlin runCatching

I am trying to use Kotlin runCatching feature along with response + error translation functions. Something like
class SomeClassThatCallsServiceX {
fun remoteCall(input): TransformedResult {
kotlin.runCatching{ serviceX.call(input)}
.onSuccess { return functionToTranslateServiceXResponse(it)}
.onFailure{ throw functionToranslateServiceXError(it)}
}
}
functionToTranslateServiceXResponse : (OriginalResult) -> TransformedResult
functionToranslateServiceXError : (Throwable) -> RuntimeException
However Kotlin is giving me the following error - A 'return' expression required in a function with a block body ('{...}'). If you got this error after the compiler update, then it's most likely due to a fix of a bug introduced in 1.3.0 (see KT-28061 for details)
Running with Kotlin 1.4.
I am still new to Kotlin- wondering if I am doing something fundamentally wrong here. Any help would be greatly appreciated.
Update: tried the following pattern, basic test cases seem to be working fine. Would love to know what others think of the pattern
class SomeClassThatCallsServiceX {
fun remoteCall(input): TransformedResult {
return kotlin.runCatching{ serviceX.call(input)}
.mapCatching(functionToTranslateServiceXResponse)
.onFailure(functionToranslateServiceXError)
.getOrThrow()
}
}
functionToTranslateServiceXResponse : (OriginalResult) -> TransformedResult
functionToranslateServiceXError : (Throwable) -> Unit
I think there are couple of issues here:
class SomeClassThatCallsServiceX {
// You are not returning `TransformedResult` but Result<TransformedResult>
// but Result cannot be returned by kotlin https://stackoverflow.com/q/52631827/906265
fun remoteCall(input) {
// error mentioned that "return" was missing but you cannot return Result
kotlin.runCatching{ serviceX.call(input)}
.onSuccess { return functionToTranslateServiceXResponse(it) }
.onFailure{ throw functionToranslateServiceXError(it) }
}
}
Having a callback could be a solution (pseudocode):
fun remoteCall(input Any, callback: Callback) {
kotlin.runCatching{ serviceX.call(input)}
.onSuccess { callback.success(it) }
.onFailure { callback.error(it) }
}
Have a tiny example on Kotlin Playground website based on the above https://pl.kotl.in/W8wMDEzN1

Kotlin Null pointer exception

I'm trying to display emails of users stored in firebase database.
I've this below code
snapsListView = findViewById(R.id.snapsList)
val adapter = emails?.let { ArrayAdapter(this, android.R.layout.simple_list_item_1, it) }
snapsListView?.adapter = adapter
auth.currentUser?.uid?.let { FirebaseDatabase.getInstance().getReference().child("users").child(it).child("snaps").addChildEventListener(object: ChildEventListener{
override fun onChildAdded(snapshot: DataSnapshot, previousChildName: String?) {
emails?.add(snapshot.child("from").value as String)
adapter?.notifyDataSetChanged()
try {
for(x in emails!!){
Log.i("Emails", x)
}
} catch (e: Exception) {
e.printStackTrace()
}
}
Emails are present in the database and as per the hierrarchy also, users-> uid->snaps and snaps contains the email in "from"
Don't know what is causing this error, or how do i resolve this.
Always getting null pointer exception
By using !! operator you have asserted that emails is not null. However, Kotlin thrown runtime exception because emails is null actually. Consider replacing !! with safe-access:
emails?.let { for (x in it) Log.i("Emails", x) }

errorBody with retrofit2 and kotlin

I am trying to get the error returned by a service (when starting with invalid credentials) rest api but for some reason errorBody does not catch it from my answer.
The correct answer I receive without problems but when I get an error I can't solve what the server sends me.
Sorry for my English, I had to use the translator
This is the part where I should get the error
override fun postLogin(callback: OperationCallBack<ResponseToken>, user: Login) {
call = Api.build()?.login(user)
call?.enqueue(object :Callback<ResponseToken>{
override fun onFailure(call: Call<ResponseToken>, t: Throwable) {
callback.onError(t.message)
}
override fun onResponse(call: Call<ResponseToken>, response: Response<ResponseToken>) {
Log.v(TAG, "ErrorMensaje: ${response.message()}")
Log.v(TAG, "ErrorBodyToString: ${response.errorBody().toString()}")
response.body()?.let {
if(response.isSuccessful && (it.isSuccess())){
Log.v(TAG, "token ${it.token}")
callback.onSuccess(it)
}else{
Log.v(TAG, "token ${it.token}")
callback.onError("Error ocurrido")
}
}
}
})
}
errorBody shows me only with toString otherwise it returns null. With toString this is what I get
2020-06-10 19:26:05.095 26590-26590/com.umbani.umbani V/CONSOLE: ErrorMensaje:
2020-06-10 19:26:05.095 26590-26590/com.umbani.umbani V/CONSOLE: ErrorBodyToString: okhttp3.ResponseBody$Companion$asResponseBody$1#fcb3843
The okHttp console shows the error as it comes from the server, which I cannot catch
D/OkHttp: {"success":true,"error":{"message":"Invalid credentials"}}
It is not a problem to convert with Gson or another converter. I can do that. I have done so with the positive response.
I have seen many answers on StackOverFlow and none has helped me.
Thank you
UPDATE:
I found the solution in this answer:
https://stackoverflow.com/a/55835083/10372439
SOLUTION:
Replace toString () to string ()
response.errorBody()!!.string()
Try overriding the onFailure block, then cast it with the right object
override fun onFailure(call: Call< ResponseToken >, t: Throwable) {
if (t is HttpException) {
try {
val errorStringRaw: String? = t.response()?.errorBody()?.string()
//Parse error message; format is api specific; we can't make a generic approach for this as of the moment
val type = object : TypeToken<ResponseBody?>() {}.type
val response: ResponseBody = Gson().fromJson(errorStringRaw, type)
} catch (e: Exception) {
}
}
}