What does SuspensionError mean?

Why does this code:

def link_click(self, sender, **event_args):
  user = sender.parent.item
  print user
  print dict(user)

Return this error?

<LiveObject: anvil.tables.Row>
SuspensionError: Cannot call a function that blocks or suspends here
at RepeatingUserItem, line 27

Edit (2021) - this solution is no longer necessary - calling dict(user) will work correctly


In the current implementation, making a dict out of a database row requires a round-trip to the server, which block until the server responds. Due to the way our Python-to-Javascript compiler works*, there are a few corner cases where it can’t handle blocking code. Probably the biggest remaining one is the dict() constructor.

You can work around it like this: dict(list(user)). This is because the list constructor does the (blocking) iteration over the database row, and then hands a (non-blocking-to-iterate) list to the dict constructor. This is on our list to fix, but in the meantime this is how to work around it.


*If you’re interested in the details, check out my talk about it at PyCon US last year

5 Likes

Hi @meredydd, sorry to get an old topic alive, but do you have any idea why this operation would return the same error?
(the sorting one)

    data=self.repeating_panel_1.items
    sorted_data = sorted(data, key=lambda k: k['column_1'])
    self.repeating_panel_1.items=sorted_Data

Thanks!

Hi @celsius878,

sorted here is raising the same error as calling dict in the example above, it’s blocking while getting the column values to sort by, and the compiler once again can’t handle the blocking code.

You can work around this by calling sorted (or sort() on a list) on the server,

The sorted function should also work fine on the client if the key it’s sorting by is present in the cache (in your case, if the ‘column_1’ key is present in self.repeating_panel_1.items), but this is ends up depending closely on Anvil’s caching behaviour so I’m aware it’s not ideal.

Thanks @bridget! I will try to move the operation to the server side.
Let’s sew how it perfomrs!

Just a note for anyone else (or, indeed, my future self) who comes across this in a similar scenario…

I was trying to populate a dropdown from the contents of a data table and was getting this error. All I needed to do to resolve it was create a list of single values from a particular column, and set the dropdown selection items to that list instead of the row iterator:

players = anvil.server.call('get_players')
player_names = [player['name'] for player in players]
self.players.items = player_names

While it’s ok to set the items of a repeating panel to a row iterator, it’s not ok for a dropdown selection. You need single strings (or 2-tuples IIRC).

2 Likes

3 posts were split to a new topic: SuspensionError