errors.ts
1 export class EasyShellError extends Error { 2 public readonly statusCode: number; 3 public readonly code: string; 4 5 public constructor(message: string, statusCode: number, code: string) { 6 super(message); 7 this.name = "EasyShellError"; 8 this.statusCode = statusCode; 9 this.code = code; 10 } 11 } 12 13 type HttpBody = { 14 message?: unknown; 15 }; 16 17 function getMessageFromBody(body: unknown, fallback: string): string { 18 if (typeof body === "object" && body !== null) { 19 const candidate = (body as HttpBody).message; 20 if (typeof candidate === "string" && candidate.trim().length > 0) { 21 return candidate; 22 } 23 } 24 25 return fallback; 26 } 27 28 export function mapHttpError(status: number, body: unknown): EasyShellError { 29 if (status === 401) { 30 return new EasyShellError( 31 getMessageFromBody(body, "Authentication expired. Please verify credentials and retry."), 32 status, 33 "AUTH_EXPIRED", 34 ); 35 } 36 37 if (status === 403) { 38 return new EasyShellError( 39 getMessageFromBody(body, "Forbidden. You do not have permission for this operation."), 40 status, 41 "FORBIDDEN", 42 ); 43 } 44 45 if (status === 404) { 46 return new EasyShellError( 47 getMessageFromBody(body, "Resource not found."), 48 status, 49 "NOT_FOUND", 50 ); 51 } 52 53 if (status === 449) { 54 return new EasyShellError( 55 getMessageFromBody(body, "Operation requires approval before execution."), 56 status, 57 "APPROVAL_REQUIRED", 58 ); 59 } 60 61 if (status >= 500) { 62 return new EasyShellError( 63 getMessageFromBody(body, "EasyShell server error. Please retry later."), 64 status, 65 "SERVER_ERROR", 66 ); 67 } 68 69 return new EasyShellError( 70 getMessageFromBody(body, `HTTP ${status} request failed.`), 71 status, 72 "HTTP_ERROR", 73 ); 74 } 75 76 export function toMcpError(error: unknown): { 77 content: Array<{ type: "text"; text: string }>; 78 isError: true; 79 } { 80 if (error instanceof EasyShellError) { 81 return { 82 content: [ 83 { 84 type: "text", 85 text: `[${error.code}] ${error.message}`, 86 }, 87 ], 88 isError: true, 89 }; 90 } 91 92 if (error instanceof Error) { 93 return { 94 content: [ 95 { 96 type: "text", 97 text: error.message, 98 }, 99 ], 100 isError: true, 101 }; 102 } 103 104 return { 105 content: [ 106 { 107 type: "text", 108 text: "Unknown error occurred.", 109 }, 110 ], 111 isError: true, 112 }; 113 }