Boardgame.io: Caller needs to know whether move returned as `INVALID_MOVE`

Created on 29 Mar 2020  Â·  3Comments  Â·  Source: boardgameio/boardgame.io

It would be useful to also know the reason of the invalid move, so allow for some extra data specific to the game.

feature

Most helpful comment

Of the approaches that we've discussed so far, I think I'm leaning toward moves returning an error object.

All 3 comments

To continue the thread from Gitter. Couple of options/considerations:

Move syntax

Moves could throw an error


Code examples

// define custom error class
class InvalidMoveError extends Error {
  constructor(data) {
    super('INVALID_MOVE');
    this.name = "InvalidMoveError";
    this.data = data;
  }
}

```js
// move definition
const { InvalidMoveError } = require('boardgame.io/core');

function move() {
// move is invalid, throw an error
throw new InvalidMoveError({ message: 'something went wrong', player: '2' });
}

```js
// process move
try {
  moveFn(G, ctx, ...args);
} catch (error) {
  if (!(error instanceof InvalidMoveError)) throw error;
  // return error.data to client
}

Notes

  • It’s idiomatic Javascript — an invalid move is an error.

Moves could return an error object


Code examples

// define error creator
function InvalidMove(data) {
  return { error: 'INVALID_MOVE', data }; // for example
}

```js
const { InvalidMove } = require('boardgame.io/core');

function move() {
// move is invalid, return an error object
return InvalidMove({ message: 'something went wrong', player: '2' });
}

```js
// process move
const result = moveFn(G, ctx, ...args);
if (result && result.error === 'INVALID_MOVE') {
  // move is invalid, return result.data the client
}

Notes

  • This is a little closer to the current return INVALID_MOVE approach than throwing an error.

ctx could have an error method

On the surface this seems pretty similar to an InvalidMove function to me, just that the function is attached to ctx instead of exported in core.

The major advantage of this would presumably be that it could hook into ctx in deeper ways — perhaps firing other kinds of changes to state or flow. What would those be?

Client handling

How does the client receive the invalid move response? Currently when a move returns INVALID_MOVE the reducer logs an error to the console and unchanged state is returned:


Reducer code

https://github.com/boardgameio/boardgame.io/blob/167690c5db2b2bfa09e432439a7948c50049b77a/src/core/reducer.ts#L155-L164

It’s worth noting that most of the error logging calls in the reducer, could potentially also benefit from reporting to the client what went wrong.


I feel like the error should not be returned within or alongside state, because it’s really a response to the imperative API that moves provide, and the error is client-specific, not a global event, but then I’m not sure how the client should get the error object.

It’s actually a broader architectural problem: the client moves are synchronous functions you fire off and hope all goes well, but under the hood these can trigger asynchronous or error-producing code. There’s no way of knowing directly when or if they’ve completed or if they were successful; you just observe the state changes the move may cause. This API is pretty nice for most simple use cases, but it has its drawbacks. It’s also a problem with multiplayer scenarios, where we don’t know if a server call timed out etc. (e.g. #218). Are there standard patterns for reducer errors or errors in general when using a Flux approach?

One way to work around the asynchronous issue is to return a Promise from the move dispatcher. We just need to ensure that the client can still be called in a synchronous way when using an in-memory store.

Of the approaches that we've discussed so far, I think I'm leaning toward moves returning an error object.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

haoyangnz picture haoyangnz  Â·  5Comments

julienroulle picture julienroulle  Â·  9Comments

nicolodavis picture nicolodavis  Â·  6Comments

iCrashed picture iCrashed  Â·  4Comments

SaFrMo picture SaFrMo  Â·  7Comments