UTIL_AsyncChain.ChainContext
Class
global inherited sharing class UTIL_AsyncChain.ChainContextShared state container passed between chain steps. Provides key-value storage for inter-step communication and access to chain metadata such as execution ID and correlation ID.
Example
context.put('accountId', account.Id);
Id accountId = (Id)context.get('accountId');
Boolean hasKey = context.has('accountId');Methods
| Method | Description |
|---|---|
| global Object get(String key) | Retrieves a value from the context by key. |
| global Object getAs(String key, Type targetType) | Retrieves a value from the context and deserializes it to the specified type. |
| global Integer getAttempt() | The 1-based attempt number of the currently executing step. |
| global String getChainExecutionId() | Returns the ID of the AsyncChainExecution__c record tracking this chain. |
| global String getCorrelationId() | Returns the correlation ID for this chain, used for log correlation across transactions. |
| global Integer getCurrentStepIndex() | Returns the zero-based index of the currently executing step. |
| global UTIL_AsyncChain.StepResult getPreviousStepResult() | Returns the result of the most recently completed step. |
| global Boolean has(String key) | Checks whether the context contains a value for the given key. |
| global String idempotencyKey() | Returns the step-level idempotency key for the currently executing step: the chain execution id joined to the step index. |
| global String idempotencyKey(Id recordId) | Returns the record-grain idempotency key for a step that fans out over many records: the step-level key joined to the given record id. |
| global String idempotencyKey(String grain) | Returns a custom-grain idempotency key for a step that fans out over a unit that is not a record id (for example a line number or an external key): the step-level key joined to the given grain. |
| global Boolean isFinalAttempt() | True when no further retry remains for the currently executing step — the strategy's budget is exhausted (or no strategy is configured), so a failure now is final. |
| global void put(String key, Object value) | Stores a value in the context under the given key. |
get
global Object get(String key)Retrieves a value from the context by key.
Parameters
| Parameter | Type | Description |
|---|---|---|
key | String | The key to look up. |
Returns Object — The stored value, or null if not found.
Example
Object value = context.get('recordCount');getAs
global Object getAs(String key, Type targetType)Retrieves a value from the context and deserializes it to the specified type. Useful for retrieving complex objects that were stored via put() and serialized between transactions.
Parameters
| Parameter | Type | Description |
|---|---|---|
key | String | The key to look up. |
targetType | Type | The Apex Type to deserialize the value into. |
Returns Object — The deserialized value, or null if the key is not found.
Example
List<String> names = (List<String>)context.getAs('nameList', List<String>.class);getAttempt
global Integer getAttempt()The 1-based attempt number of the currently executing step. 1 on the first attempt and for every step without a retry strategy; increments per retry.
Returns Integer — The 1-based attempt number of the currently executing step.
getChainExecutionId
global String getChainExecutionId()Returns the ID of the AsyncChainExecution__c record tracking this chain.
Returns String — The chain execution record ID.
Example
String executionId = context.getChainExecutionId();getCorrelationId
global String getCorrelationId()Returns the correlation ID for this chain, used for log correlation across transactions.
Returns String — The correlation ID string.
Example
String correlationId = context.getCorrelationId();getCurrentStepIndex
global Integer getCurrentStepIndex()Returns the zero-based index of the currently executing step. To build a replay-safe key for this step, call context.idempotencyKey() rather than composing the execution id and step index by hand.
Returns Integer — The current step index, or null for contexts not yet assigned to a step.
Example
String key = context.idempotencyKey();
String rowKey = context.idempotencyKey(recordId);getPreviousStepResult
global UTIL_AsyncChain.StepResult getPreviousStepResult()Returns the result of the most recently completed step. Returns null for the first step.
Returns UTIL_AsyncChain.StepResult — The previous step's StepResult, or null if this is the first step.
Example
UTIL_AsyncChain.StepResult previous = context.getPreviousStepResult();
if(previous != null && previous.success)
{
String message = previous.message;
}has
global Boolean has(String key)Checks whether the context contains a value for the given key.
Parameters
| Parameter | Type | Description |
|---|---|---|
key | String | The key to check. |
Returns Boolean — True if the key exists in the context, false otherwise.
Example
if(context.has('accountId'))
{
Id accountId = (Id)context.get('accountId');
}idempotencyKey
global String idempotencyKey()Returns the step-level idempotency key for the currently executing step: the chain execution id joined to the step index. The key stays identical when the same step replays, so a step that does one logical unit of work can store this key on an external-id field and upsert (a replay updates the same record instead of creating a duplicate), or stamp it on a marker for a side effect that cannot be upserted (a callout, an email) and skip when the marker is already present. Treat the result as an opaque token: compare it or store it whole, and do not split it to read back the run or step (use getChainExecutionId() and getCurrentStepIndex() for those). Call it from within a step's work(context), where the step index is always assigned.
Returns String — The step-level key, the execution id + "-" + step index.
Example
String key = context.idempotencyKey();global String idempotencyKey(Id recordId)Returns the record-grain idempotency key for a step that fans out over many records: the step-level key joined to the given record id. Use it so a replay after a partial failure only reprocesses the rows that did not complete the first time, instead of re-running or skipping the whole step. A null recordId falls back to the bare step-level key. An 18-character Id keeps the whole key well under the 255-character external-id limit, so this overload needs no length caveat. Treat the result as an opaque token. Pass a literal null as a typed variable or a cast ((Id) null), because a bare idempotencyKey(null) is ambiguous between this overload and the String overload.
Parameters
| Parameter | Type | Description |
|---|---|---|
recordId | Id | The record being processed, used as the per-record grain. |
Returns String — The step-level key + "-" + recordId, or the bare step-level key when recordId is null.
Example
String rowKey = context.idempotencyKey(record.Id);global String idempotencyKey(String grain)Returns a custom-grain idempotency key for a step that fans out over a unit that is not a record id (for example a line number or an external key): the step-level key joined to the given grain. A null or blank grain falls back to the bare step-level key. The grain passes through verbatim, so the helper never hashes or truncates it. The composed key is typically stored on a Text external-id field capped at 255 characters; an over-long key fails loudly at upsert with a STRING_TOO_LONG DmlException (not silent truncation), so it surfaces in your own test. If you need a long composite grain, shorten it yourself (a one-line hash of just the grain) before passing it. Treat the result as an opaque token. Pass a literal null as a typed variable or a cast ((String) null), because a bare idempotencyKey(null) is ambiguous between this overload and the Id overload.
Parameters
| Parameter | Type | Description |
|---|---|---|
grain | String | The stable fan-out token, kept short, that does not change between attempts. |
Returns String — The step-level key + "-" + grain, or the bare step-level key when grain is blank.
Example
String lineKey = context.idempotencyKey('orderLine-' + lineNumber);isFinalAttempt
global Boolean isFinalAttempt()True when no further retry remains for the currently executing step — the strategy's budget is exhausted (or no strategy is configured), so a failure now is final. Retry-aware steps should branch on isFinalAttempt() for last-chance side effects, e.g. alerting.
Returns Boolean — True when a failure of the current attempt is final; false when a retry remains.