Hermes PostgreSQL
    Preparing search index...

    Class HermesConsumerAlreadyTakenError

    Error thrown when a consumer with the same name and partition key is already running.

    This error occurs when attempting to create a PostgreSQL replication slot that's already in use by another consumer instance. Only one consumer per (consumerName, partitionKey) combination can run at a time.

    1. Multiple instances of the same service running without different partition keys
    2. Crashed process left a replication slot active (will eventually timeout)
    3. Configuration error using the same consumer name across different services
    // Instance 1
    const outbox1 = createOutboxConsumer({
    // ...
    consumerName: 'my-service',
    partitionKey: 'instance-1' // Different partition
    })

    // Instance 2
    const outbox2 = createOutboxConsumer({
    // ...
    consumerName: 'my-service',
    partitionKey: 'instance-2' // Different partition
    })
    async function startWithRetry(outbox: OutboxConsumer, maxRetries = 3) {
    for (let i = 0; i < maxRetries; i++) {
    try {
    return await outbox.start()
    } catch (error) {
    if (error instanceof HermesConsumerAlreadyTakenError) {
    console.log(`Consumer taken, retrying in 5s (${i + 1}/${maxRetries})...`)
    await new Promise(resolve => setTimeout(resolve, 5000))
    } else {
    throw error
    }
    }
    }
    throw new Error('Failed to start consumer after retries')
    }
    -- Check active replication slots
    SELECT * FROM pg_replication_slots;

    -- Drop the slot (only if you're sure the other consumer is dead)
    SELECT pg_drop_replication_slot('hermes_my_service_default');
    try {
    const stop = await outbox.start()
    } catch (error) {
    if (error instanceof HermesConsumerAlreadyTakenError) {
    console.error(
    `Consumer '${error.params.consumerName}' ` +
    `with partition '${error.params.partitionKey}' is already running`
    )

    // Option: Use a different partition key
    // Option: Wait and retry
    // Option: Alert ops team
    } else {
    throw error
    }
    }
    // Use environment-based partition keys
    const outbox = createOutboxConsumer({
    // ...
    consumerName: 'order-service',
    partitionKey: process.env.INSTANCE_ID || 'default'
    })

    Hierarchy

    Index

    Constructors

    • Creates a new HermesConsumerAlreadyTakenError.

      Parameters

      • params: { consumerName: string; partitionKey: string }

        The consumer name and partition key that are already taken

        • ReadonlyconsumerName: string

          The consumer name that's already taken

        • ReadonlypartitionKey: string

          The partition key of the consumer that's already taken

      Returns HermesConsumerAlreadyTakenError

    Properties

    cause?: unknown
    details?: HermesErrorDetails<{ consumerName: string; partitionKey: string }>
    message: string
    name: string
    stack?: string
    stackTraceLimit: number

    The Error.stackTraceLimit property specifies the number of stack frames collected by a stack trace (whether generated by new Error().stack or Error.captureStackTrace(obj)).

    The default value is 10 but may be set to any valid JavaScript number. Changes will affect any stack trace captured after the value has been changed.

    If set to a non-number value, or set to a negative number, stack traces will not capture any frames.

    Methods

    • Creates a .stack property on targetObject, which when accessed returns a string representing the location in the code at which Error.captureStackTrace() was called.

      const myObject = {};
      Error.captureStackTrace(myObject);
      myObject.stack; // Similar to `new Error().stack`

      The first line of the trace will be prefixed with ${myObject.name}: ${myObject.message}.

      The optional constructorOpt argument accepts a function. If given, all frames above constructorOpt, including constructorOpt, will be omitted from the generated stack trace.

      The constructorOpt argument is useful for hiding implementation details of error generation from the user. For instance:

      function a() {
      b();
      }

      function b() {
      c();
      }

      function c() {
      // Create an error without stack trace to avoid calculating the stack trace twice.
      const { stackTraceLimit } = Error;
      Error.stackTraceLimit = 0;
      const error = new Error();
      Error.stackTraceLimit = stackTraceLimit;

      // Capture the stack trace above function b
      Error.captureStackTrace(error, b); // Neither function c, nor b is included in the stack trace
      throw error;
      }

      a();

      Parameters

      • targetObject: object
      • OptionalconstructorOpt: Function

      Returns void

    • Indicates whether the argument provided is a built-in Error instance or not.

      Parameters

      • error: unknown

      Returns error is Error