Registry / http-networking / phin-retry

phin-retry

JSON →
library2.0.0jsnpmunverified

phin-retry is an ultra-lightweight Node.js HTTP client that wraps the `phin` library, adding robust retry and delay capabilities. It aims to provide a similar API experience to the now-deprecated `request-promise` library, making it familiar for developers transitioning from older HTTP clients. The current stable version is 2.0.0. While a specific release cadence isn't defined, it typically updates in response to `phin`'s evolution or community needs. Key differentiators include customizable retry strategies (based on network errors, HTTP status codes, or custom logic), configurable exponential or fixed delays between retries, and flexible error handling strategies. It supports standard HTTP methods (GET, POST, PUT, DELETE, PATCH) and exposes all underlying `phin` options, allowing for fine-grained control over requests. Its lightweight nature and focus on resilient API calls make it particularly suitable for microservices or applications requiring dependable external API interactions.

npm install phin-retry
INSTALL
IMPORT
SIG · PHIN-RETRY
P
phin-retry
http-networkingjavascriptv2.0.0
Install
—
Import
—
Disk
—
Pass rate
0/ 6
Env Coverage0 / 6
glibc
18–22
musl
18–22
Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
node 18–226 runs
build_error
glibc
node 18–226 runs
build_error
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

request
✓ const request = require('phin-retry');
✗ import request from 'phin-retry';
This is the primary CommonJS import pattern shown in the documentation. The package exports a default object with HTTP methods (get, post, etc.) directly.
request
✓ import request from 'phin-retry';
✗ const request = require('phin-retry');
For ES Module environments, this pattern *may* work if the package provides a default ESM export or is transpiled. However, the documentation primarily features CommonJS examples, so verify compatibility if issues arise.
phin
✓ const { phin } = require('phin-retry'); // or const request = require('phin-retry'); const phinInstance = request.phin;
The underlying `phin` instance can be accessed via `request.phin` for direct calls to `phin` or for advanced configurations that are not directly exposed by `phin-retry`'s wrapper.

Demonstrates basic GET and POST requests, including custom retry logic for server errors and authentication with tailored error and delay strategies using a local dummy server and public API.

const request = require('phin-retry'); const http = require('http'); // For a local server example // --- Dummy local server for demonstration purposes --- const server = http.createServer((req, res) => { if (req.url === '/api/post' && req.method === 'POST') { let body = ''; req.on('data', chunk => { body += chunk.toString(); }); req.on('end', () => { console.log('Received POST body:', body); res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ received: JSON.parse(body), status: 'success' })); }); } else if (req.url === '/api/delete' && req.method === 'DELETE') { const authHeader = req.headers.authorization; if (authHeader === 'Basic bmFtZTpzZWNyZXQ=') { // base64 for name:secret res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ status: 'deleted' })); } else { res.writeHead(401, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ status: 'unauthorized' })); } } else if (req.url === '/error' && req.method === 'GET') { const failCount = (server.failCount || 0); if (failCount < 2) { server.failCount = failCount + 1; res.writeHead(500, { 'Content-Type': 'text/plain' }); res.end('Internal Server Error (simulated)'); } else { server.failCount = 0; res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end('Success after retries!'); } } else { res.writeHead(404); res.end(); } }); const PORT = 9393; server.listen(PORT, async () => { console.log(`Dummy server running on http://localhost:${PORT}`); try { // Example 1: Simple GET request console.log('\n--- Example: Simple GET ---'); const getResponse = await request.get('https://jsonplaceholder.typicode.com/posts/1'); console.log('GET Response Status:', getResponse.statusCode); console.log('GET Response Body (first 100 chars):', getResponse.body.slice(0, 100)); // Example 2: POST request with retry and delay console.log('\n--- Example: POST with Retry & Delay ---'); const postResponse = await request.post({ url: `http://localhost:${PORT}/api/post`, body: { msg: 'input' }, retry: 3, delay: 500 }); console.log('POST Response Status:', postResponse.statusCode); console.log('POST Response Body:', JSON.parse(postResponse.body)); // Example 3: DELETE request with custom retry/error/delay strategy console.log('\n--- Example: DELETE with Custom Strategies ---'); const deleteResponse = await request.delete({ url: `http://localhost:${PORT}/api/delete`, auth: { user: 'name', pass: 'secret' }, errorStrategy: ({ response, error }) => { if (error) return true; // Retry on network error if (response.statusCode >= 400 && response.statusCode !== 401) return false; return true; // Consider other 4xx codes as retryable }, retryStrategy: ({ response, error, options }) => { if (error) return true; if (options.method === 'DELETE' && response.statusCode === 401) return true; if (response.statusCode >= 200 && response.statusCode < 300) return false; return true; }, delayStrategy: ({ error }) => { if (error) return 5000; return 2000; }, retry: 2 }); console.log('DELETE Response Status:', deleteResponse.statusCode); console.log('DELETE Response Body:', JSON.parse(deleteResponse.body)); // Example 4: GET with retries due to server error console.log('\n--- Example: GET with Server Error Retries ---'); const errorRetryResponse = await request.get({ url: `http://localhost:${PORT}/error`, retry: 3, delay: 200 }); console.log('Error Retry Response Status:', errorRetryResponse.statusCode); console.log('Error Retry Response Body:', errorRetryResponse.body); } catch (err) { console.error('\nAn error occurred during request examples:', err.message); if (err.response) { console.error('Error Response Status:', err.response.statusCode); console.error('Error Response Body:', err.response.body); } } finally { server.close(() => console.log('\nDummy server closed.')); } });
Debug
Known issues
breakingResponses with status codes less than 200 or greater than or equal to 300 are automatically thrown as errors by default, unlike some other HTTP clients (e.g., `request-promise`).
fix
Implement a custom `errorStrategy` function in your request options to override the default behavior and handle non-2xx status codes as desired without throwing, or wrap calls in `try/catch` blocks.
affects: >=2.0.0
gotchaThe documentation primarily uses CommonJS `require()` syntax. While Node.js generally supports both, direct ESM `import` might require specific project configuration or different import paths depending on the package's module resolution.
fix
For ESM projects, try `import request from 'phin-retry'` or `import * as request from 'phin-retry'`. If issues persist, consider using `require()` within an ESM wrapper or verify `package.json` `exports` field configuration.
affects: >=2.0.0
gotchaBy default, `phin-retry` only retries once on network errors or status codes >= 500, with a relatively short delay. This default behavior might not be sufficient for highly unstable external services or specific retry requirements.
fix
Explicitly configure the `retry` option (number of retries), `delay` (milliseconds), and provide custom `retryStrategy` and `delayStrategy` functions in your request options to fine-tune retry behavior for specific endpoints or error types.
affects: >=2.0.0
Errors
Common errors & fixes
TypeError: request.get is not a function
This usually indicates an incorrect import or require statement, or attempting to use `request` before it's properly assigned, or outside an async context when using `await`.
fix
Ensure you are using `const request = require('phin-retry');` for CommonJS environments. If using ESM, try `import request from 'phin-retry';` and confirm your file is treated as an ES module. Also, ensure `await` calls are within an `async` function.
UnhandledPromiseRejectionWarning: Error: Bad status code: 404
The default `errorStrategy` in `phin-retry` throws an error for any response with a status code < 200 or >= 300 (e.g., 4xx, 5xx).
fix
Wrap the `await request(...)` call in a `try...catch` block to handle the thrown error, or provide a custom `errorStrategy` option in your request configuration to prevent `phin-retry` from throwing on specific status codes.
ReferenceError: require is not defined
Attempting to use the CommonJS `require()` function in an ES Module (ESM) context.
fix
Change your import statement from `const request = require('phin-retry');` to `import request from 'phin-retry';`. Additionally, ensure your `package.json` specifies `"type": "module"` or that the file ends with a `.mjs` extension.
Upgrade
Version history
2.0.0latest on npm
Audit
Dependencies
phinrequiredCore HTTP client library that phin-retry wraps and extends with retry logic.
Agent activity
4 hits · last 30 days
node
4
Resources
phin-retry — npm install phin-retry · libregistry