/** * Result 辅助工具函数 * 提供统一的错误处理和 Result 操作方法 */ import { Result } from './result'; import type { TextRankError, TextRankResult, AsyncTextRankResult } from '../types'; import { ErrorType } from '../types'; /** * 创建 TextRankError */ export function createError( type: ErrorType, message: string, cause?: Error, context?: Record ): TextRankError { // exactOptionalPropertyTypes 下可选属性不能显式赋 undefined,按需附加 const error: TextRankError = { type, message }; if (cause !== undefined) { error.cause = cause; } if (context !== undefined) { error.context = context; } return error; } /** * 创建成功的 Result */ export function ok(value: T): TextRankResult { return Result.ok(value) as TextRankResult; } /** * 创建失败的 Result */ export function err(error: TextRankError): TextRankResult { return Result.error(error); } /** * 创建失败的 Result (简化版) */ export function errOf( type: ErrorType, message: string, cause?: Error, context?: Record ): TextRankResult { return Result.error(createError(type, message, cause, context)); } /** * 安全执行同步函数,返回 Result */ export function safeSync( fn: () => T, errorType: ErrorType = ErrorType.COMPUTATION_ERROR, context?: Record ): TextRankResult { try { const result = fn(); return Result.ok(result) as TextRankResult; } catch (error) { return Result.error( createError( errorType, error instanceof Error ? error.message : String(error), error instanceof Error ? error : undefined, context ) ) as TextRankResult; } } /** * 安全执行异步函数,返回 AsyncResult */ export async function safeAsync( fn: () => Promise, errorType: ErrorType = ErrorType.COMPUTATION_ERROR, context?: Record ): AsyncTextRankResult { try { const result = await fn(); return Result.ok(result) as TextRankResult; } catch (error) { return Result.error( createError( errorType, error instanceof Error ? error.message : String(error), error instanceof Error ? error : undefined, context ) ) as TextRankResult; } } /** * 将普通的 Promise 转换为 AsyncResult */ export async function fromPromise( promise: Promise, errorType: ErrorType = ErrorType.COMPUTATION_ERROR, context?: Record ): AsyncTextRankResult { try { const result = await promise; return Result.ok(result) as TextRankResult; } catch (error) { return Result.error( createError( errorType, error instanceof Error ? error.message : String(error), error instanceof Error ? error : undefined, context ) ) as TextRankResult; } } /** * 检查输入参数的有效性 */ export function validateInput(text: string, minLength = 1): TextRankResult { if (!text || typeof text !== 'string') { return errOf(ErrorType.VALIDATION_ERROR, '文本内容不能为空且必须为字符串类型', undefined, { text, type: typeof text, }); } if (text.trim().length < minLength) { return errOf(ErrorType.VALIDATION_ERROR, `文本长度不能少于 ${minLength} 个字符`, undefined, { text: text.trim(), length: text.trim().length, minLength, }); } return Result.ok(text.trim()); } /** * 组合多个 Result,全部成功才返回成功 */ export function combineResults(results: TextRankResult[]): TextRankResult { const values: T[] = []; for (const result of results) { if (result.isError()) { return err(result.error); } values.push(result.value); } return Result.ok(values); } /** * 映射 Result 的值 */ export function mapResult( result: TextRankResult, mapper: (value: T) => U ): TextRankResult { return result.map(mapper) as TextRankResult; } /** * 链式处理 Result */ export function chainResult( result: TextRankResult, chainer: (value: T) => TextRankResult ): TextRankResult { if (result.isOk()) { return chainer(result.value); } else { return err(result.error); } } /** * 提供默认值处理失败的 Result */ export function withDefault(result: TextRankResult, defaultValue: T): T { return result.getOrDefault(defaultValue); } /** * 记录错误日志 */ export function logError(error: TextRankError, prefix = 'TextRank'): void { console.error(`[${prefix}] ${error.type}:`, error.message); if (error.cause) { console.error('原因:', error.cause); } if (error.context) { console.error('上下文:', error.context); } } /** * 处理 Result,成功时执行 onOk,失败时执行 onErr */ export function handleResult( result: TextRankResult, onOk: (value: T) => U, onErr: (error: TextRankError) => U ): U { if (result.isOk()) { return onOk(result.value); } else { return onErr(result.error); } } /** * 超时处理包装器 */ export async function withTimeout( promise: Promise, timeoutMs: number, context?: Record ): AsyncTextRankResult { const timeoutPromise = new Promise((_, reject) => { setTimeout(() => { reject( createError(ErrorType.TIMEOUT_ERROR, `操作超时(${timeoutMs}ms)`, undefined, { timeout: timeoutMs, ...context, }) ); }, timeoutMs); }); try { const result = await Promise.race([promise, timeoutPromise]); return Result.ok(result) as TextRankResult; } catch (error) { if (error instanceof Error && error.message.includes('操作超时')) { return Result.error(error as unknown as TextRankError) as TextRankResult; } return Result.error( createError( ErrorType.COMPUTATION_ERROR, error instanceof Error ? error.message : String(error), error instanceof Error ? error : undefined, context ) ) as TextRankResult; } }