Vague exception "code 2" from generated Unity API

Hi folks,

When I call the generated API from Unity, I get back a vague exception I haven’t been able to track down:

{"code":2,"message":"Exception was thrown by handler.","details":[]}

I’ve compared my service extension against the latest guildservice sample to make sure I didn’t miss any changes. I’ve synced it up as fully as I can tell, and got make build working again. But I’m still getting this exception. Here’s the callstack of the thrown exception:

UnityEngine.Debug:LogWarningFormat (string,object[])
AccelByte.Core.AccelByteLogHandler:PrintLog (AccelByte.Core.AccelByteLogType,object,UnityEngine.Object) (at ./Library/PackageCache/com.accelbyte.unitysdk@26536c3380/Runtime/Core/Logger/AccelByteLogHandler.cs:70)
AccelByte.Core.AccelByteLogHandler:InvokeLog (AccelByte.Core.AccelByteLogType,object) (at ./Library/PackageCache/com.accelbyte.unitysdk@26536c3380/Runtime/Core/Logger/AccelByteLogHandler.cs:24)
AccelByte.Core.AccelByteDebug:InvokeLog (AccelByte.Core.AccelByteLogType,object) (at ./Library/PackageCache/com.accelbyte.unitysdk@26536c3380/Runtime/Core/Logger/AccelByteDebug.cs:155)
AccelByte.Core.AccelByteDebug:LogWarning (object) (at ./Library/PackageCache/com.accelbyte.unitysdk@26536c3380/Runtime/Core/Logger/AccelByteDebug.cs:96)
AccelByte.Core.Report:GetHttpResponse (UnityEngine.Networking.UnityWebRequest) (at ./Library/PackageCache/com.accelbyte.unitysdk@26536c3380/Runtime/Core/Report.cs:74)
AccelByte.Core.WebRequestSchedulerAsync/<Update>d__4:MoveNext () (at ./Library/PackageCache/com.accelbyte.unitysdk@26536c3380/Runtime/Core/Http/WebRequestSchedulerAsync.cs:41)
System.Threading.Tasks.TaskCompletionSource`1<UnityEngine.Networking.UnityWebRequest/Result>:TrySetResult (UnityEngine.Networking.UnityWebRequest/Result)
AccelByte.Core.UnityWebRequestExtension/<>c__DisplayClass3_0:<GetAwaiter>b__0 (UnityEngine.AsyncOperation) (at ./Library/PackageCache/com.accelbyte.unitysdk@26536c3380/Runtime/Core/UnityWebRequestExtension.cs:63)
UnityEngine.AsyncOperation:InvokeCompletionEvent ()

I’ve made the method it’s calling in the actual service extension just return static data (like Hello World) and there’s no change. I haven’t been able to track down what code throws this exception, either. Do you have any ideas?

Thanks, Chris

Hi Chris,

I’m Eric Chan, an SE from the Extend team.
First, we have a couple of questions :

  1. Did you have previous success in using the Accelbyte Unity SDK?
  2. Which exact Accelbyte Unity library and the version are you using?
  3. Which generated API are you calling?
  4. Possible if you can attach some code snippets, or better yet the project?
  5. Which service extension is in the AGS Starter environment? I saw two - is it the “guildservice” or the other one?

Thanks!
Eric

Hi Eric!

  1. This is the first time I’ve had the generated Unity API try to talk to the service extension.
  2. We have the AccelByte Unity SDK v16.2.0, installed via github/AB/accelbyte-unity-sdk.git. The API is generated via the latest template and codegen binaries as of yesterday.
  3. and 4. Here is the API call:
		ApiClient apiClient = MultiRegistry.GetApiClient();
		Thing thingService = apiClient.GetApi<Thing, ThingApi>();

		thingService.ThingserviceGetThingState(thingId, playerId, ThingserviceResultCallback);

All the result callback does is check if there was an error, and there is, the exception as described.

  1. The other one. I haven’t gone through the hassle of generating an SDK for guildservice and integrating it with our Unity project.

Thanks, Chris

I checked the AB settings (AccelByte->Edit Settings) and noticed that they were stale, apparently using old client info. The client info specifically didn’t match what the service extension uses. I updated both Development and Default (we’re currently using the dev environment) to match what my service extension uses, but that didn’t change anything.

I tried updating to the latest Unity SDK but ran into compile errors so I rolled it back. I’ll have to look at that separately.

Followup question:

It looks like there’s one client ID and one client secret per service extension. What if we want to use two different service extensions in the same Unity project?

Hi @chrislambertus,

@ericc checked for logs and here is what he got (after thing-ifying it):

info: AccelByte.ExtensionThing.Server.DebugLoggerServerInterceptor[0]
      REQUEST Grpc.Core.Metadata
fail: AccelByte.ExtensionThing.Server.DebugLoggerServerInterceptor[0]
      Error thrown by /accelbyte.custom.thing.Thingservice/GetThingState.
      AccelByte.Sdk.Core.HttpResponseException: {"error":"invalid_client","error_description":"unknown client"}
         at AccelByte.Sdk.Api.Iam.Operation.TokenGrantV3.ParseResponse(HttpStatusCode code, String contentType, Stream payload)
         at AccelByte.Sdk.Api.Iam.Wrapper.OAuth20.TokenGrantV3(TokenGrantV3 input)
         at AccelByte.Sdk.Core.AccelByteSDK.LoginClient(Action`1 onTokenReceived)
         at AccelByte.Sdk.Feature.AutoTokenRefresh.Sdk_ExtensionMethods.LoginClient(AccelByteSDK sdk, Boolean autoRefresh, Single refreshThreshold)
         at AccelByte.ExtensionThing.Server.DefaultAccelByteServiceProvider..ctor(IConfiguration config, ILogger`1 logger) in /build/Classes/DefaultAccelByteServiceProvider.cs:line 43
         at System.RuntimeMethodHandle.InvokeMethod(Object target, Span`1& arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
         at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
         at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
         at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
         at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite callSite, RuntimeResolverContext context)
         at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
         at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
         at Microsoft.Extensions.DependencyInjection.ServiceProvider.CreateServiceAccessor(Type serviceType)
         at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
         at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
         at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, Boolean isDefaultParameterRequired)
         at lambda_method5(Closure , IServiceProvider , Object[] )
         at Grpc.AspNetCore.Server.Internal.DefaultGrpcServiceActivator`1.Create(IServiceProvider serviceProvider)
         at Grpc.Shared.Server.UnaryServerMethodInvoker`3.ResolvedInterceptorInvoker(TRequest resolvedRequest, ServerCallContext resolvedContext)
         at Grpc.Shared.Server.UnaryServerMethodInvoker`3.ResolvedInterceptorInvoker(TRequest resolvedRequest, ServerCallContext resolvedContext)
         at AccelByte.ExtensionThing.Server.DebugLoggerServerInterceptor.UnaryServerHandler[TRequest,TResponse](TRequest request, ServerCallContext context, UnaryServerMethod`2 continuation) in /build/Classes/DebugLoggerServerInterceptor.cs:line 32
fail: Grpc.AspNetCore.Server.ServerCallHandler[6]
      Error when executing service method 'GetThingState'.
      AccelByte.Sdk.Core.HttpResponseException: {"error":"invalid_client","error_description":"unknown client"}
         at AccelByte.Sdk.Api.Iam.Operation.TokenGrantV3.ParseResponse(HttpStatusCode code, String contentType, Stream payload)
         at AccelByte.Sdk.Api.Iam.Wrapper.OAuth20.TokenGrantV3(TokenGrantV3 input)
         at AccelByte.Sdk.Core.AccelByteSDK.LoginClient(Action`1 onTokenReceived)
         at AccelByte.Sdk.Feature.AutoTokenRefresh.Sdk_ExtensionMethods.LoginClient(AccelByteSDK sdk, Boolean autoRefresh, Single refreshThreshold)
         at AccelByte.ExtensionThing.Server.DefaultAccelByteServiceProvider..ctor(IConfiguration config, ILogger`1 logger) in /build/Classes/DefaultAccelByteServiceProvider.cs:line 43
         at System.RuntimeMethodHandle.InvokeMethod(Object target, Span`1& arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)

Looking at the logs it seems to be from either an incorrect combination of client ID, client secret, and maybe even an incorrect base URL.

This aligns with your observation:

I checked the AB settings (AccelByte->Edit Settings) and noticed that they were stale, apparently using old client info.


It looks like there’s one client ID and one client secret per service extension. What if we want to use two different service extensions in the same Unity project?

It is also possible to create a confidential IAM client and share it between two (2) service extensions.

Hi @chrislambertus

So we took a peek at your Extend App in the Admin Portal, and guess what? We noticed something funky going on in the Environment Secret Configuration section. It seems like the client ID and client secret values are playing a game of switcheroo when compared to what’s listed in the IAM clients list.

This is probably due to the environment variables list in Admin Portal not being consistently sorted resulting in quirky mishaps.

You just need to correct the values and make sure that the client ID goes into AB_CLIENT_ID and the client secret goes into AB_CLIENT_SECRET field.

Elmer, Thanks :stuck_out_tongue_winking_eye:

edit: added clarification on how to fix the issue

Aha! That appears to be it.

In the Admin Portal “Environment Secrets” section, I’ve been used to the order of

  • Client ID
  • Client Secret

And used that pattern everywhere else. However, the vars there were swapped for whatever reason.
After I got them in the right order, I don’t seem to be getting the errors now!

Is there anyway for that exception to be a bit more informative?

Thanks, Chris

Hey there, Chris!

Just wanted to drop you a quick update: the team’s already on it and has created a ticket to enhance the exception messaging.

Cheers!

2 Likes