# Chain of Responsability

## About

This pattern helps in creating failovers for Objects, so that if one of them fails another one will try to execute the logic.

Like a `chain` at each failure to execute, `next` object is called, retrying the execution.

{% hint style="info" %}
It is possible to implement a `retry` on the service failed, before calling `next`.
{% endhint %}

## Example

Lets suppose we have services to process payments, like `PjBankGateway` and `CieloBankGateway` which is a gateway for an external service.&#x20;

So we will try to process the payment with one of them, and if for some reason it fails it will automatically try to run the payment process with the other.

{% code title="PaymentProcessor.ts" %}

```typescript
export default interface PaymentProcessor {
    next?: PaymentProcessor;
    processPayment(input: Input): Promise<Output>;
}

export class PjBankProcessor implements PaymentProcessor {
    constructor(readonly next?: PaymentProcessor) {}
    
    async processPayment(input: Input): Promise<Output> {
        try {
            const pjBankGateway = new PjBankGateway();
            return await pjBankGateway.createTransaction(input);
        } catch(error: any) {
            if (!this.next) throw new Error('Out of processors.');
            return this.next.processPayment(input);
        }
    }
}

export class CieloBankProcessor implements PaymentProcessor {    
    constructor(readonly next?: PaymentProcessor) {}
    
    async processPayment(input: Input): Promise<Output> {
        try {
            const cieloBankGateway = new CieloBankGateway();
            return await cieloBankGateway.createTransaction(input);
        } catch(error: any) {
            if (!this.next) throw new Error('Out of processors.');
            return this.next.processPayment(input);
        }
    }
}
```

{% endcode %}

{% hint style="warning" %}
The way done bellow is not necessarily the only way.

You could for instance create a class that would in some way chain the `Processors`.
{% endhint %}

{% code title="Main.ts" %}

```typescript
const cieloProcessor = new CieloBankProcessor();
const pjBankProcessor = new PjBankProcessor(cieloProcessor);

// This is Typescript way with Annotations and Registry Pattern to inject Dependencies
Registry.getInstance().provide('paymentProcessor', pjBankProcessor);
```

{% endcode %}
