Skip to main content

Advanced Usage

This page covers advanced features of Nitro Fetch, including retry logic, custom error handling, extending the NitroFetch class, and more.

Retry Logic

Nitro Fetch supports automatic retries for failed requests. You can control the number of retries, delay, and custom logic for when to retry.

Basic Retry Example

const api = create({
retry: {
count: 2, // Retry up to 2 times
delay: 1000, // 1 second between retries
shouldRetry: (error) => {
// Retry only on network errors or 5xx responses
if (error instanceof Error) return true;
if (error.status && error.status >= 500) return true;
return false;
},
onRetry: (error, attempt) => {
console.warn(`Retrying (${attempt}) after error:`, error);
}
}
});

Advanced Retry Logic

You can implement more complex retry logic, such as exponential backoff:

const api = create({
retry: {
count: 3,
delay: (attempt) => Math.pow(2, attempt) * 1000, // Exponential backoff
shouldRetry: (error) => {
// Retry on specific error types
return error instanceof Error || (error.status && error.status >= 500);
},
onRetry: (error, attempt) => {
console.warn(`Retry attempt ${attempt} after error:`, error);
}
}
});

Custom Error Handling

You can handle errors globally using response interceptors, or locally with try/catch.

Global Error Handling

api.interceptors.response.use(null, error => {
// Log or transform errors globally
if (error instanceof Error) {
// Network or timeout error
alert('Network error!');
}
return Promise.reject(error);
});

Local Error Handling

try {
const res = await api.get('/unstable-endpoint');
} catch (err) {
// Handle error for this request
console.error('Request failed:', err);
}

Extending NitroFetch

You can extend the NitroFetch class to add custom methods or behaviors.

Basic Extension Example

import { NitroFetch, RequestConfig } from 'nitro-fetch';

class MyApi extends NitroFetch {
getProfile() {
return this.get('/profile');
}
}

const api = new MyApi({ baseURL: 'https://api.example.com' });
api.getProfile().then(res => console.log(res.data));

Advanced Extension Example

You can add more complex methods or override existing ones:

class MyApi extends NitroFetch {
async getProfile() {
const response = await this.get('/profile');
// Transform the response
return {
...response,
data: {
...response.data,
fullName: `${response.data.firstName} ${response.data.lastName}`
}
};
}

async postData(data: any) {
// Add custom headers or logic before sending
const config = {
headers: { 'X-Custom-Header': 'value' }
};
return this.post('/data', data, config);
}
}

Advanced Use Cases

1. Request/Response Transformation

Transform requests or responses globally:

api.interceptors.request.use(config => {
// Transform request data
if (config.data) {
config.data = JSON.stringify(config.data);
}
return config;
});

api.interceptors.response.use(response => {
// Transform response data
response.data = JSON.parse(response.data);
return response;
});

2. Authentication Token Refresh

Handle token refresh in response interceptors:

api.interceptors.response.use(null, async error => {
if (error.response && error.response.status === 401) {
// Attempt to refresh the token
const newToken = await refreshToken();
if (newToken) {
// Retry the original request
error.config.headers.Authorization = `Bearer ${newToken}`;
return api.request(error.config);
}
}
return Promise.reject(error);
});

3. Request Cancellation

Cancel requests using AbortController:

const controller = new AbortController();
api.get('/data', { signal: controller.signal })
.then(res => console.log(res.data))
.catch(err => {
if (err.name === 'AbortError') {
console.log('Request was cancelled');
}
});

// Cancel the request
controller.abort();

4. Request Timeout

Set a timeout for requests:

api.get('/slow-endpoint', { timeout: 5000 })
.then(res => console.log(res.data))
.catch(err => {
if (err.name === 'TimeoutError') {
console.log('Request timed out');
}
});

5. Request/Response Logging

Log all requests and responses:

api.interceptors.request.use(config => {
console.log('Request:', config);
return config;
});

api.interceptors.response.use(response => {
console.log('Response:', response);
return response;
});

Next: API Reference — Full details on all types and methods.