DefaultApolloException: No data and no error was returned

From the PlayGround, when i pass the below payload I get correct output, but from Kotlin with Generated Model class, I am not clear how to pass the request object and capture it into response java object

query getLoyaltyInfoForCustomer {
  loyalty {
    earnPoints (iapAsinIdentifier: { asin: "TEST234dfs" }){
      pointsAmount
    }
    pointsBalance {
      availableBalance
    }
  }
}

With Below Kotlin code, the data is always null

val apolloClient = ApolloClient.Builder().serverUrl("http://myserver:8000/graphql-ide").build();

val myData = apolloClient.query(GetLoyaltyInfoForCustomerQuery(asin = "Hi")).execute()
println(myData.data); // Always prints null on console

Reference - Generated Model Class from Apollo Plugin

//
// AUTO-GENERATED FILE. DO NOT MODIFY.
//
// This class was automatically generated by Apollo GraphQL version '4.0.0-alpha.2'.
//
package com.mycompany.model

import com.amazon.appstore.cube.model.adapter.GetLoyaltyInfoForCustomerQuery_ResponseAdapter
import com.amazon.appstore.cube.model.adapter.GetLoyaltyInfoForCustomerQuery_VariablesAdapter
import com.amazon.appstore.cube.model.selections.GetLoyaltyInfoForCustomerQuerySelections
import com.apollographql.apollo3.annotations.ApolloAdaptableWith
import com.apollographql.apollo3.api.CompiledField
import com.apollographql.apollo3.api.CompositeAdapter
import com.apollographql.apollo3.api.CustomScalarAdapters
import com.apollographql.apollo3.api.Query
import com.apollographql.apollo3.api.json.JsonWriter
import com.apollographql.apollo3.api.obj
import kotlin.Boolean
import kotlin.Int
import kotlin.String
import kotlin.Unit

public data class GetLoyaltyInfoForCustomerQuery(
  public val asin: String,
) : Query<GetLoyaltyInfoForCustomerQuery.Data> {
  public override fun id(): String = OPERATION_ID

  public override fun document(): String = OPERATION_DOCUMENT

  public override fun name(): String = OPERATION_NAME

  public override fun serializeVariables(
    writer: JsonWriter,
    customScalarAdapters: CustomScalarAdapters,
    withBooleanDefaultValues: Boolean,
  ): Unit {
    GetLoyaltyInfoForCustomerQuery_VariablesAdapter.serializeVariables(writer, this,
        customScalarAdapters, withBooleanDefaultValues)
  }

  public override fun adapter(): CompositeAdapter<Data> =
      GetLoyaltyInfoForCustomerQuery_ResponseAdapter.Data.obj()

  public override fun rootField(): CompiledField = CompiledField.Builder(
    name = "data",
    type = com.amazon.appstore.cube.model.type.Query.type
  )
  .selections(selections = GetLoyaltyInfoForCustomerQuerySelections.__root)
  .build()

  @ApolloAdaptableWith(GetLoyaltyInfoForCustomerQuery_ResponseAdapter.Data::class)
  public data class Data(
    public val loyalty: Loyalty?,
  ) : Query.Data

  public data class Loyalty(
    public val earnPoints: EarnPoints?,
    public val pointsBalance: PointsBalance?,
  )

  public data class EarnPoints(
    public val pointsAmount: Int?,
  )

  public data class PointsBalance(
    public val availableBalance: Int?,
  )

  public companion object {
    public const val OPERATION_ID: String =
        "56c84d29714c7e21cc9ca655fe9160c63b575d79429745cf3f48647c112ac6c9"

    /**
     * The minimized GraphQL document being sent to the server to save a few bytes.
     * The un-minimized version is:
     *
     * query getLoyaltyInfoForCustomer($asin: String!) {
     *   loyalty {
     *     earnPoints(iapAsinIdentifier: {
     *       asin: $asin
     *     }
     *     ) {
     *       pointsAmount
     *     }
     *     pointsBalance {
     *       availableBalance
     *     }
     *   }
     * }
     */
    public val OPERATION_DOCUMENT: String
      get() =
          "query getLoyaltyInfoForCustomer(${'$'}asin: String!) { loyalty { earnPoints(iapAsinIdentifier: { asin: ${'$'}asin } ) { pointsAmount } pointsBalance { availableBalance } } }"

    public const val OPERATION_NAME: String = "getLoyaltyInfoForCustomer"
  }
}

Hi!

Your code looks correct to me.

Is it possible that the asin you’re passing (Hi) has 0 results, and therefore a null data is correct? Maybe you have something in myData.errors?

Hi,

As of now we don’t have any logic implemented on GraphQL Server and just return hard coded response irrespective of the input. I have tried the same with Play Ground environment and adding a debug point, i could verify that both data and error is null. Refer screenshot

Adding Response from Playground with input “Hi”

I got it resolved. The problem was with the endpoint i was hitting.

From my code, I was hitting http://localhost:8280/graphql-ide instead of http://localhost:8280/graphql

But honestly i would expect a error or exception if the endpoint was wrong. No Data and No Error made it quite hard to debug.

Follow up question, I get the below as response and how do i cast it to a model class

Data(loyalty=Loyalty(earnPoints=EarnPoints(pointsAmount=12), pointsBalance=PointsBalance(availableBalance=73)))

How do i cast myData.data to my auto generated Loyalty model class ?

Glad you found the culprit!

Thanks to your screenshot I can see that you are using Apollo Kotlin v4, with which exceptions will be in ApolloResponse.exception (here we can see that there is a "No data and no error was returned" exception).
If you’d like the exception to be thrown, you can use ApolloResponse.dataOrThrow().
More context about this here.

How do i cast myData.data to my auto generated Loyalty model class ?

You can find it in myData.data.loyalty.
(myData should be renamed response for more clarity).

1 Like