UpdateAccountAsync SessionId

Greetings,

I am trying to create a ‘BeforeUpdateAccount’ validator that will allow for Username changes. However, I have a couple of issues:

  1. What is the correct way to block the update? I am currently throwing errors, should I instead return null? Though, I’m not sure how I would convey the reason for the failure.

  2. My sessionId is undefined. I assume this is because the call is made through the Client and not the Socket. I assume this is because you can use this method without a Socket connection? However, there is no corresponding Socket version, so I have no session… I need the session in order to notify other users that the name has been changed. I typically do the notifications this way:

nk.streamUserUpdate(context.userId, context.sessionId, { mode: 1, subject: context.userId }, false, false, JSON.stringify({ "cmd": "newname", "name": account.displayName }));

In this case the session is required for the stream update as I am getting the following error:

nakama_1       | {"level":"error","ts":"2023-04-27T15:19:55.137Z","caller":"server/runtime_javascript.go:551","msg":"JavaScript runtime function raised an uncaught exception","mode":"before","id":"/nakama.api.nakama/updateaccount","error":"TypeError: expects string at github.com/heroiclabs/nakama/v3/server.(*runtimeJavascriptNakamaModule).streamUserUpdate.func1 (native)"}

Thank you

Well, I figured out #2 above, at least, I found a solution, let me know if this is a bad solution…

Here’s what I did to find the session. This API call can only be made once the user actually is online with a valid Socket. So, I 'm not worried that they won’t have a session. Also, I have code that kicks out previous sessions, so I assume the session count will always be 0.

var presence = nk.streamUserList({ mode: 1, subject: context.userId });
// Just reassigning the context here, as it's used in the streamUserUpdate method
context.sessionId = presence.find((d) => d.userId == context.userId)?.sessionId;

Thanks again

For #1 above I found this:

  1. Throwing an exception causes the API call to fail and then retry based on the configured retry behavior. Which is not what I intended.

  2. If I instead return null, I get an error that specifies
    "One or more errors occurred. (Requested resource was not found.)

On the server I see:

nakama_1       | {"level":"warn","ts":"2023-04-27T19:27:12.772Z","caller":"server/api_account.go:139","msg":"Intercepted a disabled resource.","resource":"/nakama.api.Nakama/UpdateAccount","uid":"0ca33fe0-e006-475b-b9cc-4ada116d9754"}

Which I imagine is the error from returning null.

If this is correct, I’ll proceed to use it this way…

(1) Yes if you’d like to block an account update I think the proper way in this case would be to return an error. It may depend a bit on what the criteria is but I don’t think it’s an anti-pattern. You should return a 400-error which won’t be retried on by the client.

(2) To notify other users about the username change, I’d recommend using the notifications API rather than raw streams. This will allow the pending notification to be stored for offline users and thus you won’t need a sessionID.

  1. Ok, I’ll have to look up how to return an error. I don’t think I’ve ever seen a typescript example.

  2. I don’t need the notification for offline users, but that makes sense, I actually did consider that. Is there any performance issues from doing it as a stream message vs a notification? Other than the need to lookup the session?

@sesposito is there any way for @Meneleus to return a 400 to the client in Typescript? Otherwise another approach may be needed.

@Meneleus notifications just use streams under the hood. I can’t speak to the exact details of your game but using notifications this way is in line with their design.

Sounds good. Thank you! I await the answer about errors, there are other places it would be nice to be able to return errors.

@Meneleus you can return custom errors as described here: Heroic Labs Documentation | TypeScript Runtime.

The mappings between the error codes and http statuses are found here: nakama-common/index.d.ts at master · heroiclabs/nakama-common · GitHub.

Thank you Sir. Lots of goodies on that page. I don’t know how I missed it…