Hone logo
Hone
Problems

Angular Interceptor Chain Implementation

This challenge focuses on building a flexible interceptor chain in Angular. Interceptors are a powerful mechanism for modifying HTTP requests and responses globally, but managing multiple interceptors can become complex. This task requires you to design and implement a system that allows for easy addition, removal, and reordering of interceptors within a chain, ensuring each interceptor has the opportunity to modify requests or responses before they reach the backend or the application.

Problem Description

You need to create an Angular service that manages a chain of HTTP interceptors. This service should allow you to:

  1. Add Interceptors: Add new interceptor functions to the chain. Each interceptor function should accept a request object and return a modified request object (or the original if no modification is needed).
  2. Remove Interceptors: Remove interceptors from the chain by their index or by a unique identifier.
  3. Reorder Interceptors: Change the order of interceptors in the chain.
  4. Execute the Chain: Provide a method that takes an HTTP request object and executes the interceptor chain, applying each interceptor sequentially. The final modified request object should be returned.
  5. Handle Errors: If any interceptor throws an error, the chain execution should stop, and the error should be propagated.

Key Requirements:

  • The interceptor chain should be implemented as an Angular service.
  • Interceptors should be functions that accept and return HttpClientRequest objects (you can use the standard Angular HttpClient request object for this).
  • The service should provide methods for adding, removing, and reordering interceptors.
  • The chain execution should be synchronous.
  • The service should be testable.

Expected Behavior:

  • Adding an interceptor should insert it into the chain at the specified position.
  • Removing an interceptor should remove it from the chain without affecting other interceptors.
  • Reordering interceptors should change their execution order.
  • Executing the chain should apply each interceptor in the specified order, modifying the request object as needed.
  • Error handling should prevent the chain from continuing after an error occurs.

Edge Cases to Consider:

  • Empty interceptor chain.
  • Adding an interceptor at an invalid index.
  • Removing an interceptor that doesn't exist.
  • Interceptors throwing errors.
  • Multiple interceptors modifying the same property of the request object.

Examples

Example 1:

Input:
  - Initial chain: []
  - Add interceptor 1: (req) => ({...req, header: 'Interceptor 1'})
  - Add interceptor 2: (req) => ({...req, header: 'Interceptor 2'})
  - Execute chain with: {url: 'https://example.com', method: 'GET'}

Output:
{ url: 'https://example.com', method: 'GET', header: 'Interceptor 2' }

Explanation: Interceptor 1 adds 'Interceptor 1' to the header, and Interceptor 2 overwrites it with 'Interceptor 2'.

Example 2:

Input:
  - Initial chain: [interceptor1, interceptor2]
  - interceptor1: (req) => ({...req, method: 'POST'})
  - interceptor2: (req) => ({...req, body: {data: 'test'}})
  - Execute chain with: {url: 'https://example.com', method: 'GET'}

Output:
{ url: 'https://example.com', method: 'POST', body: { data: 'test' } }

Explanation: Interceptor 1 changes the method to POST, and Interceptor 2 adds a body.

Example 3: (Error Handling)

Input:
  - Initial chain: [interceptor1, interceptor2]
  - interceptor1: (req) => ({...req, method: 'POST'})
  - interceptor2: (req) => { throw new Error("Interceptor Error"); }
  - Execute chain with: {url: 'https://example.com', method: 'GET'}

Output:
Error: Interceptor Error

Explanation: Interceptor 2 throws an error, halting the chain execution and propagating the error.

Constraints

  • The service must be written in TypeScript and compatible with Angular 14 or later.
  • The interceptor functions should be pure functions (no side effects).
  • The chain execution should be synchronous.
  • The service should be designed for testability.
  • The maximum number of interceptors in the chain should be limited to 10.

Notes

  • Consider using an array to store the interceptors.
  • Think about how to handle errors gracefully within the chain.
  • Focus on creating a clean and maintainable design.
  • You don't need to implement the actual HTTP request sending; this challenge focuses solely on the interceptor chain logic. You can use a mock HttpClientRequest object for testing.
  • Consider using unique identifiers for interceptors to make removal easier.
Loading editor...
typescript