#getting constraint error when creating user

1 messages · Page 1 of 1 (latest)

solar hornet
#
fn register_user(ctx: context.Context, req: wisp.Request) {
  use json <- wisp.require_json(req)

  let result = {
    use input <- result.try(
      decode.run(json, register_decoder())
      |> result.replace_error(errors.BadRequest(
        "missing email, username, or password",
      )),
    )

    let validation = {
      validator.new()
      |> users.validate_username(input.username)
      |> users.validate_email(input.email)
      |> users.validate_password(input.password)
    }

    use _ <- result.try(validator.valid(validation))

    use password_bits <- result.try(users.hash_password(input.password))

    users.create_user(ctx, input.username, input.email, password_bits)
  }

  case result {
    Ok(_) -> helpers.message_response("user created", 201)
    Error(err) -> errors.handle_error(req, err)
  }
}

pub fn create_user(ctx: context.Context, username, email, password) {
  sql.create_user(username, email, password, helpers.current_time())
  |> db.exec(ctx.db, _)
  |> result.map_error(errors.DatabaseError)
}

pub fn exec(db: Connection, b: #(String, List(dev.Param))) {
  let query_string = b.0
  let params = b.1

  case db {
    Pog(conn) -> {
      query_string
      |> pog.query()
      |> list.fold(params, _, fn(acc, param) {
        let param = parrot_to_pog(param)
        pog.parameter(acc, param)
      })
      |> pog.execute(conn)
    }
    Mock(handler) -> {
      case handler(query_string, params) {
        Ok(returned) -> Ok(pog.Returned(returned.count, []))
        Error(err) -> Error(err)
      }
    }
  }
}
INFO 2026-02-11T18:23:45.812875652+07:00 201 POST /api/register
EROR 2026-02-11T18:23:45.850050641+07:00 POST /api/register constraint violated: { message:duplicate key value violates unique constraint "users_username_key" constraint: users_username_key detail: Key (username)=(test3) already exists. }
#

The table is completely empty, there's no test3 user

#

the user is created, but because of the error, the server returns 500 instead of 201

#

I'm completely puzzled, there shouldn't be anything wrong

#
-- schema
CREATE TABLE if not exists users (
    id bigserial primary key,
    username varchar(255) unique not null,
    email citext unique not null,
    password_hash bytea not null,
    created_at bigint not null
);
pub fn create_user(
  username username: String,
  email email: String,
  password_hash password_hash: BitArray,
  created_at created_at: Int,
) {
  let sql =
    "INSERT INTO users (username, email, password_hash, created_at)
VALUES ($1, $2, $3, $4)"
  #(sql, [
    dev.ParamString(username),
    dev.ParamString(email),
    dev.ParamBitArray(password_hash),
    dev.ParamInt(created_at),
  ])
}
dark moss
#

the log makes it seem like there are two requests, the first one is 201 and the second one fails

solar hornet
dark moss
#

are you calling it twice with the same username from your client?

solar hornet
#

i'm testing with api client

#

should be once unless my mouse double clicks

#

tried with curl and it's the same

solar hornet
#

wait nevermind, in my log request middleware I return handler() instead of response