MCP Terminal Server

/** * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { Registry } from './registry.js'; import { httpStatusCode, type StatusName } from './statusTypes.js'; export { StatusName }; export interface HttpErrorWireFormat { details?: unknown; message: string; status: StatusName; } /** * Base error class for Genkit errors. */ export class GenkitError extends Error { source?: string; status: StatusName; detail?: any; code: number; // For easy printing, we wrap the error with information like the source // and status, but that's redundant with JSON. originalMessage: string; constructor({ status, message, detail, source, }: { status: StatusName; message: string; detail?: any; source?: string; }) { super(`${source ? `${source}: ` : ''}${status}: ${message}`); this.originalMessage = message; this.code = httpStatusCode(status); this.status = status; this.detail = detail; this.name = 'GenkitError'; } /** * Returns a JSON-serializable representation of this object. */ public toJSON(): HttpErrorWireFormat { return { // This error type is used by 3P authors with the field "detail", // but the actual Callable protocol value is "details" ...(this.detail === undefined ? {} : { details: this.detail }), status: this.status, message: this.originalMessage, }; } } export class UnstableApiError extends GenkitError { constructor(level: 'beta', message?: string) { super({ status: 'FAILED_PRECONDITION', message: `${message ? message + ' ' : ''}This API requires '${level}' stability level.\n\nTo use this feature, initialize Genkit using \`import {genkit} from "genkit/${level}"\`.`, }); this.name = 'UnstableApiError'; } } /** * assertUnstable allows features to raise exceptions when using Genkit from *more* stable initialized instances. * * @param level The maximum stability channel allowed. * @param message An optional message describing which feature is not allowed. */ export function assertUnstable( registry: Registry, level: 'beta', message?: string ) { if (level === 'beta' && registry.apiStability === 'stable') { throw new UnstableApiError(level, message); } } /** * Creates a new class of Error for issues to be returned to users. * Using this error allows a web framework handler (e.g. express, next) to know it * is safe to return the message in a request. Other kinds of errors will * result in a generic 500 message to avoid the possibility of internal * exceptions being leaked to attackers. * In JSON requests, code will be an HTTP code and error will be a response body. * In streaming requests, { code, message } will be passed as the error message. */ export class UserFacingError extends GenkitError { constructor(status: StatusName, message: string, details?: any) { super({ status, detail: details, message }); super.name = 'UserFacingError'; } } export function getHttpStatus(e: any): number { if (e instanceof GenkitError) { return e.code; } return 500; } export function getCallableJSON(e: any): HttpErrorWireFormat { if (e instanceof GenkitError) { return e.toJSON(); } return { message: 'Internal Error', status: 'INTERNAL', }; } /** * Extracts error message from the given error object, or if input is not an error then just turn the error into a string. */ export function getErrorMessage(e: any): string { if (e instanceof Error) { return e.message; } return `${e}`; } /** * Extracts stack trace from the given error object, or if input is not an error then returns undefined. */ export function getErrorStack(e: any): string | undefined { if (e instanceof Error) { return e.stack; } return undefined; }