AshOban error: key :transaction? not found in: nil

Hello,

Following up this tutorial: Send Emails with Ash, I tried to setup audit logs workers by setting up resource:

defmodule Mgx.AuditLogs.Workers.CreateAuditLog do
  use Ash.Resource,
    data_layer: AshPostgres.DataLayer,
    domain: Mgx.AuditLogs,
    extensions: [AshOban],
    otp_app: :mgx

  postgres do
    table "audit_logs_background_jobs"
    repo Mgx.RepoBackgroundsJobs
  end

  oban do
    domain Mgx.AuditLogs

    triggers do
      trigger :add_audit_log do
        action :process
        where expr(state == :pending or state == :failed)
        on_error(:failed)
        
        

        log_final_error?(true)
      end
    end
  end

  actions do
    defaults [:read, :destroy, create: :*, update: :*]

    default_accept [
      :state,
      :actor_id,
      :actor_type,
      :action,
      :resource_id,
      :resource_type,
      :created_at
    ]

    update :process do
      accept [:state]

      change set_attribute(:state, :added)

      description "Mark the background job as processed. This is will run with oban triggers."

      change after_transaction(fn _changeset, {:ok, result}, _context ->
               Mgx.AuditLogs.create_audit_log(
                 actor_id: result.actor_id,
                 actor_type: result.actor_type,
                 action: result.action,
                 resource_id: result.resource_id,
                 resource_type: result.resource_type,
                 created_at: result.created_at
               )
             end)
    end
  end

  attributes do
    uuid_primary_key :id

    attribute :state, :atom do
      allow_nil? false

      description "The state of the background job."

      constraints one_of: [:pending, :added, :failed]

      default :pending
    end

    attribute :actor_id, :uuid do
      allow_nil? false

      description "The id of the actor that has performed the action."
    end

    attribute :actor_type, :string do
      allow_nil? false

      description "The type of the actor: e.g 'user', 'system'."
    end

    attribute :action, :string do
      allow_nil? false

      description "The action performed. Example: 'create', 'update', 'delete'."
    end

    attribute :resource_id, :uuid do
      allow_nil? false

      description "The id of the resource on which the action was performed."
    end

    attribute :resource_type, :string do
      allow_nil? false

      description "The type of the resource."
    end

    attribute :created_at, :utc_datetime do
      allow_nil? false

      description "The timestamp when the action was performed."
    end

    timestamps()
  end
end

But i am getting Runtime Error like this:

== Compilation error in file lib/mgx/audit_logs/workers/create_audit_log.ex ==
** (RuntimeError) Exception in transformer AshOban.Transformers.DefineSchedulers on Mgx.AuditLogs.Workers.CreateAuditLog: 

key :transaction? not found in: nil

If you are using the dot syntax, such as map.field, make sure the left-hand side of the dot is a map
    (ash_oban 0.3.1) lib/transformers/define_schedulers.ex:296: AshOban.Transformers.DefineSchedulers.define_worker/4
    (ash_oban 0.3.1) lib/transformers/define_schedulers.ex:23: anonymous fn/3 in AshOban.Transformers.DefineSchedulers.transform/1
    (elixir 1.18.0) lib/enum.ex:2546: Enum."-reduce/3-lists^foldl/2-0-"/3
    (ash_oban 0.3.1) lib/transformers/define_schedulers.ex:15: AshOban.Transformers.DefineSchedulers.transform/1
    (spark 2.2.40) lib/spark/dsl/extension.ex:639: anonymous fn/4 in Spark.Dsl.Extension.run_transformers/4
    (elixir 1.18.0) lib/enum.ex:4964: Enumerable.List.reduce/3
    (elixir 1.18.0) lib/enum.ex:2600: Enum.reduce_while/3
    /home/user/MGX/lib/mgx/audit_logs/workers/create_audit_log.ex:1: (file)

I’ve tried looking at the documentation but can’t find where I should set the transaction? key that the error mentions. Neither oban nor trigger sections seem to accept this key.

This is the config:

config :mgx, Oban,
  repo: Mgx.RepoBackgroundsJobs,
  engine: Oban.Engines.Basic,
  notifier: Oban.Notifiers.Postgres,
  queues: [default: 10]

Application.ex:

  children = [
      MgxWeb.Telemetry,
      Mgx.Repo,
      Mgx.RepoAudit,
      Mgx.RepoBackgroundsJobs,
      {DNSCluster, query: Application.get_env(:mgx, :dns_cluster_query) || :ignore},
      {Oban,
       AshOban.config(
         Application.fetch_env!(:mgx, :ash_domains),
         Application.fetch_env!(:mgx, Oban)
       )},
....

The migrations order is:

  1. Migrations for oban
  2. Migrations for init extensions for ash

I can’t figure out where might be the problem. Any help would be greatly appreciated! Let me know if you need any additional information.

We should address this with a better error, but the on_error action has to be an existing update or destroy action on the resource. Please open an issue suggesting a better error message for that situation :bowing_man:

1 Like

Thank you, on_error changed to existing update, . But there are 2 things I would like to address.

  1. on_error update documentation says, we get :error as argument, What will will the type of it? will it be :map?
update :failed do
      accept [:state]
      
      # TODO: Add error handling
      argument :error, type

      change set_attribute(:state, :failed)

      description "Mark the background job as failed. This is will run with oban triggers."
    end
  1. Shall I open an issue, for better message and also type of argument type for it in the documentation?
1 Like

It will be an exception, so you can set the type to :struct

1 Like

I see. Thank you

1 Like

Thank you for the issue! :bowing_man: Forgot to respond to #2 saying that yes an issue & docs PR are welcome.

1 Like