qapinterface
Version:
Comprehensive API utilities for Node.js applications including authentication, security, request processing, and response handling with zero external dependencies
105 lines (91 loc) • 2.73 kB
JavaScript
/**
* HTTP Response Validator
* Single Responsibility: Validate HTTP Response objects and throw on errors ONLY
*/
/**
* Throws an error if the Response is not ok (status 200-299)
* @param {Response} res - Fetch API Response object
* @throws {Error} Throws error with status code and response text/statusText
* @returns {Promise<void>} Resolves if response is ok
*/
async function throwIfResNotOk(res) {
if (!res) {
throw new Error('Response object is required');
}
if (typeof res.ok !== 'boolean') {
throw new Error('Invalid Response object: missing ok property');
}
if (!res.ok) {
let errorText = res.statusText || 'Unknown error';
try {
// Try to get response body text for more detailed error info
const responseText = await res.text();
if (responseText) {
errorText = responseText;
}
} catch (textError) {
// If we can't read the response text, fall back to statusText
// This can happen if the response body was already consumed
console.warn('Could not read response text for error details:', textError.message);
}
throw new Error(`${res.status}: ${errorText}`);
}
}
/**
* Validates response and returns it if ok, throws if not ok
* @param {Response} res - Fetch API Response object
* @returns {Promise<Response>} The same response object if valid
* @throws {Error} Throws error with status code and response text/statusText
*/
async function validateAndReturnResponse(res) {
await throwIfResNotOk(res);
return res;
}
/**
* Checks if a Response object is ok without throwing
* @param {Response} res - Fetch API Response object
* @returns {boolean} True if response is ok, false otherwise
*/
function isResponseOk(res) {
if (!res || typeof res.ok !== 'boolean') {
return false;
}
return res.ok;
}
/**
* Gets error information from a Response object without throwing
* @param {Response} res - Fetch API Response object
* @returns {Promise<object>} Error details with status, statusText, and text
*/
async function getResponseError(res) {
if (!res) {
return {
status: 0,
statusText: 'No response object',
text: 'Response object is null or undefined'
};
}
if (res.ok) {
return null; // No error for ok responses
}
let responseText = res.statusText || 'Unknown error';
try {
const text = await res.text();
if (text) {
responseText = text;
}
} catch (textError) {
// Keep the statusText as fallback
}
return {
status: res.status,
statusText: res.statusText,
text: responseText
};
}
module.exports = {
throwIfResNotOk,
validateAndReturnResponse,
isResponseOk,
getResponseError
};