{"id":17332,"library":"popsicle-status","title":"Popsicle Status Middleware","description":"Popsicle Status is a middleware for the `popsicle` HTTP client library, designed to automatically reject HTTP responses with undesirable status codes. It provides a simple function, `status(min?: number, max?: number)`, which returns a middleware that validates a response's status code against a specified inclusive `min` and exclusive `max` range. By default, it rejects any status outside the 200-399 range (i.e., anything not a 2xx or 3xx success/redirection code). The current stable version is `3.0.0`. This library is actively maintained, with releases primarily aligning with major updates to its peer dependencies, `popsicle` and `servie`, to ensure compatibility. Its key differentiator is its seamless integration into the `popsicle` middleware chain, simplifying error handling by transforming invalid HTTP responses into thrown errors, making control flow clearer than manual status checks.","status":"active","version":"3.0.0","language":"javascript","source_language":"en","source_url":"git://github.com/blakeembrey/popsicle-status","tags":["javascript","popsicle","plugin","status","http","response","typescript"],"install":[{"cmd":"npm install popsicle-status","lang":"bash","label":"npm"},{"cmd":"yarn add popsicle-status","lang":"bash","label":"yarn"},{"cmd":"pnpm add popsicle-status","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Peer dependency required for middleware signature compatibility, especially since v3.0.0 which refactored for Servie 4 support.","package":"servie","optional":false}],"imports":[{"note":"The library is written in TypeScript and primarily designed for ESM consumption, though CJS builds are provided. Prefer named imports for tree-shaking and type safety.","wrong":"const { status } = require('popsicle-status');","symbol":"status","correct":"import { status } from 'popsicle-status';"},{"note":"While `popsicle-status` produces a `Middleware` function, the `Middleware` type itself is typically imported from `popsicle` or `servie` if needed for type annotations.","wrong":"import { Middleware } from 'popsicle-status';","symbol":"Middleware","correct":"import type { Middleware } from 'popsicle';"}],"quickstart":{"code":"import { status } from 'popsicle-status';\nimport { Request, Response } from 'popsicle'; // Assuming popsicle types are available\n\nasync function main() {\n  const statusMiddleware = status(200, 300); // Configure to only allow 2xx responses\n\n  // Mock popsicle's internal `send` function for demonstration\n  const mockSend = async (req: Request): Promise<Response> => {\n    if (req.url === 'https://example.com/success') {\n      return { url: req.url, status: 200, statusText: 'OK', headers: {}, body: 'Success!', clone: () => ({ ...this }) } as Response;\n    }\n    if (req.url === 'https://example.com/bad-request') {\n      return { url: req.url, status: 400, statusText: 'Bad Request', headers: {}, body: 'Bad', clone: () => ({ ...this }) } as Response;\n    }\n    throw new Error('Unexpected request URL');\n  };\n\n  // Create a dummy request object\n  const createRequest = (url: string): Request => ({\n    url,\n    method: 'GET',\n    headers: {}, \n    body: null, \n    clone: () => ({ ...this }) \n  } as Request);\n\n  console.log('--- Testing a successful request (200 OK) ---');\n  try {\n    const reqSuccess = createRequest('https://example.com/success');\n    const resSuccess = await statusMiddleware(reqSuccess, mockSend);\n    console.log(`Success! Status: ${resSuccess.status}, Body: ${await resSuccess.body}`);\n  } catch (err: any) {\n    console.error(`Unexpected error for success: ${err.message}`);\n  }\n\n  console.log('\\n--- Testing a failing request (400 Bad Request) ---');\n  try {\n    const reqFail = createRequest('https://example.com/bad-request');\n    const resFail = await statusMiddleware(reqFail, mockSend); // This should throw due to status filter\n    console.log(`Unexpected success for failure: Status: ${resFail.status}`);\n  } catch (err: any) {\n    console.error(`Caught expected error: ${err.message}`);\n    if (err.res) {\n      console.log(`Error includes response object. Status: ${err.res.status}`);\n    }\n  }\n}\n\nmain();","lang":"typescript","description":"Demonstrates how to apply the `status` middleware to a `popsicle` request, configuring it to only allow 2xx responses, and handling both successful and rejected outcomes."},"warnings":[{"fix":"Update the `servie` peer dependency to `^4.0.0`. If unable to update, remain on `popsicle-status@2.x`.","message":"Version 3.0.0 introduced a refactor for 'Servie 4' compatibility. This means users of `popsicle-status` will need to ensure their `servie` peer dependency is at version 4.x.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Ensure `popsicle` is updated to version `6.x` or newer. If stuck on an older `popsicle` version, use `popsicle-status@1.x`.","message":"Version 2.0.0 updated the middleware signature to align with `popsicle@6.x`. Middleware functions now expect a different signature, which will break compatibility with older `popsicle` versions (e.g., `5.x` or earlier).","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Refactor error handling code to use `try/catch` blocks around calls that use `popsicle-status` middleware, as it will now throw an `Error` directly instead of returning a rejected promise.","message":"Version 0.2.1 changed the error handling mechanism from resolving with a `Promise` to explicitly throwing an error. Code that previously awaited a rejected promise might now require `try/catch` blocks.","severity":"breaking","affected_versions":">=0.2.1"},{"fix":"When catching errors from `popsicle-status`, you can now safely access `err.res` for the full response object if you need to inspect headers or other response details.","message":"Since version 2.0.1, the error object thrown by `popsicle-status` now includes a `res` property, providing direct access to the `Response` object that caused the error. This is not a breaking change but alters the error object's structure.","severity":"gotcha","affected_versions":">=2.0.1"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Update `popsicle` to `^6.0.0` or downgrade `popsicle-status` to `1.x` to match your `popsicle` version.","cause":"Using `popsicle-status@2.x` or higher with an incompatible version of `popsicle` (e.g., `popsicle@5.x`), leading to a mismatch in the middleware function signature.","error":"TypeError: Cannot read properties of undefined (reading 'url') or The middleware function signature is incorrect."},{"fix":"Install or update `servie` to a compatible version: `npm install servie@^4.0.0` or `yarn add servie@^4.0.0`.","cause":"`popsicle-status@3.x` requires `servie@^4.0.0` as a peer dependency, but an older or incompatible version is installed or missing.","error":"Error: Peer dependency 'servie' is not met. Required: '^4.0.0'"},{"fix":"Wrap your `popsicle` requests using `popsicle-status` middleware in `try/catch` blocks to explicitly handle the thrown `HttpError`.","cause":"Code written for `popsicle-status` versions prior to `0.2.1` that expected rejected promises for bad statuses, but `0.2.1` and later throw errors directly, leading to unhandled rejections if not caught.","error":"UnhandledPromiseRejectionWarning: HttpError: Bad Request (400)"}],"ecosystem":"npm","meta_description":null}