@ritas-inc/hanaqueryapi-client
Version:
TypeScript client for HANA Query API with full type safety and error handling
144 lines (133 loc) • 4.01 kB
text/typescript
/**
* Response Helper Functions
*
* Utility functions for safely handling API responses
*/
import { isSuccessResponse, isErrorResponse } from './types.ts';
import type { APIResponse, SuccessResponse, ErrorResponse } from './types.ts';
/**
* Safely extract data from an API response
* Returns the data if successful, or null if error
*/
export function safeExtractData<T, M>(response: APIResponse<T, M>): T | null {
if (isSuccessResponse(response)) {
return response.data;
}
return null;
}
/**
* Safely extract metadata from an API response
* Returns the metadata if successful, or null if error
*/
export function safeExtractMetadata<T, M>(response: APIResponse<T, M>): M | null {
if (isSuccessResponse(response)) {
return response.metadata ?? null;
}
return null;
}
/**
* Get error details from a response
* Returns error details if it's an error response, null otherwise
*/
export function getErrorDetails(response: APIResponse): ErrorResponse['problem'] | null {
if (isErrorResponse(response)) {
return response.problem;
}
return null;
}
/**
* Check if response indicates success
*/
export function isSuccess<T, M>(response: APIResponse<T, M>): response is SuccessResponse<T, M> {
return isSuccessResponse(response);
}
/**
* Check if response indicates error
*/
export function isError(response: APIResponse): response is ErrorResponse {
return isErrorResponse(response);
}
/**
* Transform response data safely
* Applies transform function only if response is successful
*/
export function transformResponseData<T, R, M>(
response: APIResponse<T, M>,
transform: (data: T) => R
): APIResponse<R, M> {
if (isSuccessResponse(response)) {
try {
const transformedData = transform(response.data);
return {
success: true,
data: transformedData,
metadata: response.metadata
};
} catch (error) {
// Transform failed, return error response
return {
success: false,
problem: {
status: 500,
type: 'transformation-error',
title: 'Data Transformation Failed',
detail: error instanceof Error ? error.message : 'Unknown transformation error',
instance: '/client/transform',
context: {
request: 'Data transformation',
responseText: 'Transform function threw an error'
},
issues: []
}
};
}
}
// Return original error response
return response as ErrorResponse;
}
/**
* Combine multiple responses into a single result
* All responses must be successful for the result to be successful
*/
export function combineResponses<T1, T2, M1, M2>(
response1: APIResponse<T1, M1>,
response2: APIResponse<T2, M2>
): APIResponse<{ first: T1; second: T2 }, { first: M1; second: M2 }> {
if (isSuccessResponse(response1) && isSuccessResponse(response2)) {
return {
success: true,
data: {
first: response1.data,
second: response2.data
},
metadata: {
first: response1.metadata ?? ({} as M1),
second: response2.metadata ?? ({} as M2)
}
};
}
// Return the first error found, or create a combined error
const firstError = isErrorResponse(response1) ? response1.problem : null;
const secondError = isErrorResponse(response2) ? response2.problem : null;
if (firstError && secondError) {
return {
success: false,
problem: {
status: 400,
type: 'multiple-errors',
title: 'Multiple Request Failures',
detail: 'One or more requests failed',
instance: '/client/combine',
context: {
request: 'Combined requests',
responseText: 'Multiple failures occurred'
},
issues: [
`First: ${firstError.title} - ${firstError.detail}`,
`Second: ${secondError.title} - ${secondError.detail}`
]
}
};
}
return (firstError ? response1 : response2) as ErrorResponse;
}