osc-mcp-server
Version:
Model Context Protocol server for OSC (Open Sound Control) endpoint management
174 lines • 7.82 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ErrorUtils = exports.OperationErrors = exports.ValidationErrors = exports.MessageErrors = exports.EndpointErrors = exports.NetworkErrors = void 0;
exports.createOSCError = createOSCError;
exports.formatErrorResponse = formatErrorResponse;
const index_1 = require("../types/index");
function createOSCError(code, message, details) {
return {
code,
message,
details: details || {},
};
}
class NetworkErrors {
static portInUse(port, suggestedPorts = []) {
return createOSCError(index_1.ErrorCode.PORT_IN_USE, `Port ${port} is already in use. Please try a different port.`, {
port,
suggestedPorts: suggestedPorts.length > 0 ? suggestedPorts : [port + 1, port + 2, port + 3],
});
}
static portInvalid(port) {
return createOSCError(index_1.ErrorCode.PORT_INVALID, `Invalid port number: ${port}. Port must be between 1024 and 65535.`, {
port,
validRange: { min: 1024, max: 65535 },
});
}
static permissionDenied(port) {
return createOSCError(index_1.ErrorCode.PERMISSION_DENIED, `Permission denied to bind to port ${port}. Try using a port number above 1024 or run with appropriate privileges.`, {
port,
suggestion: 'Use a port number above 1024 or run with appropriate privileges',
});
}
static networkError(message, details) {
return createOSCError(index_1.ErrorCode.NETWORK_ERROR, `Network error: ${message}`, details);
}
}
exports.NetworkErrors = NetworkErrors;
class EndpointErrors {
static notFound(endpointId) {
return createOSCError(index_1.ErrorCode.ENDPOINT_NOT_FOUND, `Endpoint '${endpointId}' not found. Please check the endpoint ID and try again.`, { endpointId });
}
static alreadyExists(endpointId, port) {
return createOSCError(index_1.ErrorCode.ENDPOINT_ALREADY_EXISTS, `An endpoint already exists on port ${port}. Each port can only have one active endpoint.`, { endpointId, port });
}
static startFailed(endpointId, reason) {
return createOSCError(index_1.ErrorCode.ENDPOINT_START_FAILED, `Failed to start endpoint '${endpointId}': ${reason}`, { endpointId, reason });
}
static alreadyActive(endpointId) {
return createOSCError(index_1.ErrorCode.ENDPOINT_ALREADY_EXISTS, `Endpoint '${endpointId}' is already active and listening.`, { endpointId });
}
static alreadyStopped(endpointId) {
return createOSCError(index_1.ErrorCode.ENDPOINT_NOT_FOUND, `Endpoint '${endpointId}' is already stopped or does not exist.`, { endpointId });
}
}
exports.EndpointErrors = EndpointErrors;
class MessageErrors {
static parseError(reason, details) {
return createOSCError(index_1.ErrorCode.MESSAGE_PARSE_ERROR, `Failed to parse OSC message: ${reason}`, details);
}
static invalidMessage(reason) {
return createOSCError(index_1.ErrorCode.INVALID_OSC_MESSAGE, `Invalid OSC message format: ${reason}`, {
reason,
});
}
static unsupportedType(typeTag) {
return createOSCError(index_1.ErrorCode.MESSAGE_PARSE_ERROR, `Unsupported OSC type tag '${typeTag}'. Supported types: i (int32), f (float32), s (string), b (blob).`, {
unsupportedType: typeTag,
supportedTypes: ['i', 'f', 's', 'b'],
});
}
}
exports.MessageErrors = MessageErrors;
class ValidationErrors {
static missingParameter(paramName) {
return createOSCError(index_1.ErrorCode.MISSING_REQUIRED_PARAMETER, `Missing required parameter: '${paramName}'`, { paramName });
}
static invalidParameter(paramName, value, expectedType) {
return createOSCError(index_1.ErrorCode.INVALID_PARAMETERS, `Invalid parameter '${paramName}': expected ${expectedType}, got ${typeof value}`, {
paramName,
providedValue: value,
expectedType,
});
}
static parameterOutOfRange(paramName, value, min, max) {
return createOSCError(index_1.ErrorCode.INVALID_PARAMETERS, `Parameter '${paramName}' value ${value} is out of range. Must be between ${min} and ${max}.`, {
paramName,
value,
validRange: { min, max },
});
}
static invalidAddressPattern(pattern) {
return createOSCError(index_1.ErrorCode.INVALID_PARAMETERS, `Invalid OSC address pattern: '${pattern}'. Address patterns must start with '/' and contain valid OSC characters.`, {
pattern,
requirements: "Must start with '/' and contain valid OSC characters",
});
}
}
exports.ValidationErrors = ValidationErrors;
class OperationErrors {
static internalError(message, details) {
return createOSCError(index_1.ErrorCode.INTERNAL_ERROR, `Internal error: ${message}`, details);
}
static operationFailed(operation, reason) {
return createOSCError(index_1.ErrorCode.OPERATION_FAILED, `Operation '${operation}' failed: ${reason}`, { operation, reason });
}
}
exports.OperationErrors = OperationErrors;
class ErrorUtils {
static fromError(error, code = index_1.ErrorCode.INTERNAL_ERROR) {
return createOSCError(code, error.message, {
originalError: error.name,
stack: error.stack,
});
}
static isNetworkError(error) {
return [
index_1.ErrorCode.PORT_IN_USE,
index_1.ErrorCode.PORT_INVALID,
index_1.ErrorCode.PERMISSION_DENIED,
index_1.ErrorCode.NETWORK_ERROR,
].includes(error.code);
}
static isRecoverable(error) {
return [
index_1.ErrorCode.PORT_IN_USE,
index_1.ErrorCode.PORT_INVALID,
index_1.ErrorCode.INVALID_PARAMETERS,
index_1.ErrorCode.MISSING_REQUIRED_PARAMETER,
].includes(error.code);
}
static getSuggestions(error) {
const suggestions = [];
switch (error.code) {
case index_1.ErrorCode.PORT_IN_USE:
suggestions.push('Try using a different port number');
if (error.details?.['suggestedPorts']) {
suggestions.push(`Suggested ports: ${error.details['suggestedPorts'].join(', ')}`);
}
break;
case index_1.ErrorCode.PORT_INVALID:
suggestions.push('Use a port number between 1024 and 65535');
break;
case index_1.ErrorCode.PERMISSION_DENIED:
suggestions.push('Use a port number above 1024');
suggestions.push('Run the application with appropriate privileges');
break;
case index_1.ErrorCode.ENDPOINT_NOT_FOUND:
suggestions.push('Check that the endpoint ID is correct');
suggestions.push('Use get_endpoint_status to see available endpoints');
break;
case index_1.ErrorCode.MESSAGE_PARSE_ERROR:
suggestions.push('Ensure the sender is using valid OSC 1.0 format');
suggestions.push('Check that the message is not corrupted');
break;
case index_1.ErrorCode.INVALID_PARAMETERS:
suggestions.push('Check the parameter types and values');
suggestions.push('Refer to the tool documentation for valid parameter formats');
break;
}
return suggestions;
}
}
exports.ErrorUtils = ErrorUtils;
function formatErrorResponse(error) {
return {
error: {
code: error.code,
message: error.message,
details: error.details,
suggestions: ErrorUtils.getSuggestions(error),
},
};
}
//# sourceMappingURL=index.js.map