Skip to content

When calling grant! for records that already have permissions inside of transactions the transaction fails without an exception message #34

@joshmfrankel

Description

@joshmfrankel

Sample code to reproduce issue

def grant_feature
  ActiveRecord::Base.transaction do
    some_role = Role.find(role_id)

    AccessControl::SomePolicy.new(some_role).grant!(:some_action)
  end
end

Exception:
Could not grant action 1 on object AccessControl::SomePolicy with id 4 for actor #Role:0x00007fa8f1f5bad0 because PG::InFailedSqlTransaction: ERROR: current transaction is aborted, commands ignored until end of transaction block

This exception is raised here:

raise Accessly::GrantError.new("Could not grant action #{action_id} on object #{object_type} for actor #{@actor} because #{e}")

But is occurring after

rescue ActiveRecord::RecordNotUnique
        nil

is encountered which basically hides the actual error.

  1. Try to grant! new permission within transaction
  2. Permission record already exists which is rescued by rescue ActiveRecord::RecordNotUnique and returns nil
  3. Transaction then fails and returns the secondary exception message: "Could not grant action 1 on object AccessControl::SomePolicy with id 4"

Underlying issue

The problem is that we're encountering an exception within a transaction which fails the transaction but is being silenced by the return of nil

Potential options

  1. I know it is trying to avoid the lookup of db records here but something like an upsert could be a better option instead of rescuing ActiveRecord::RecordNotUnique and silencing the error
  2. We could first check to see if the record exists with a find_by and then branch to create! if it doesn't or simply return nil without an rescuing a RecordNotUnique exception
  3. We could use find_or_create_by! kinda like upsert

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions