Allocate Party if it doesn't exists
I am trying to create a Daml Script that creates Users and Parties on the ledger.
createUsersAndParties = script do
let
userParties = [
("alice", "Alice"),
("bob", "Bob")]
forA_ userParties $ uncurry allocatePartyAndCreateUser
users <- listAllUsers
return (users)
allocatePartyAndCreateUser userId partyId = script do
allocatePartyWithHint partyId (PartyIdHint partyId)
userIdValidated <- validateUserId userId
createUser (User userIdValidated (Some party)) [CanActAs party]
return()
This script could potentially be run more than once, so I would like the script on the second run to just list all the users. When I change the code to the following:
createUsersAndParties = script do
let
userParties = [
("alice", "Alice"),
("bob", "Bob")]
forA_ userParties $ uncurry allocatePartyAndCreateUser
forA_ userParties $ uncurry allocatePartyAndCreateUser
users <- listAllUsers
return (users)
I get the error:
Script execution failed:
Tried to allocate a party that already exists: Alice
Is there a way to add a try catch in the allocatePartyAndCreateUser function? I have tried using GeneralError as the catch argument but that did not work?
I usually do this by checking if the user exists first. You can find an example of that in create-daml-app.
I am pasting this code snippet here for future searches that land on this page.
import DA.Text as T
getOrCreateUserParty : Text -> Script Party
getOrCreateUserParty alias = do
userId <- validateUserId (T.asciiToLower alias)
try do
User _ (Some party) <- getUser userId
pure party
catch
UserNotFound _ -> do
p <- allocatePartyWithHint alias (PartyIdHint alias)
createUser (User userId (Some p)) [CanActAs p]
pure p
I have found it sufficient for demo, test, and educational scripts.
If you use the above, then pressing r in the daml start terminal will not result in a Command allocateParty failed: INVALID_ARGUMENT: INVALID_ARGUMENT... Party already exists: party ... is already allocated on this node