Skip to main content
Glama
errors.py3.18 kB
"""Error types and response builders.""" from __future__ import annotations from typing import Any, Optional from composer_mcp.core.models import ApiResponse, ErrorDetail, Warning class ComposerError(Exception): """Base exception for composer errors.""" code: str = "UNKNOWN_ERROR" def __init__( self, message: str, field: Optional[str] = None, suggestions: Optional[list[str]] = None, ): super().__init__(message) self.message = message self.field = field self.suggestions = suggestions def to_error_detail(self) -> ErrorDetail: return ErrorDetail( code=self.code, message=self.message, field=self.field, suggestions=self.suggestions, ) class InvalidKeyError(ComposerError): """Raised when key signature is invalid.""" code = "INVALID_KEY" class InvalidNoteError(ComposerError): """Raised when note format is invalid.""" code = "INVALID_NOTE" class InvalidRangeError(ComposerError): """Raised when range is invalid (low > high or impossible).""" code = "INVALID_RANGE" class InvalidIntervalError(ComposerError): """Raised when interval format is invalid.""" code = "INVALID_INTERVAL" class InvalidChordSymbolError(ComposerError): """Raised when chord symbol cannot be parsed.""" code = "INVALID_CHORD_SYMBOL" class InvalidTimeSignatureError(ComposerError): """Raised when time signature is invalid.""" code = "INVALID_TIME_SIGNATURE" class ParseError(ComposerError): """Raised when input stream cannot be parsed.""" code = "PARSE_ERROR" class UnsatisfiableConstraintsError(ComposerError): """Raised when constraints cannot be satisfied.""" code = "UNSATISFIABLE_CONSTRAINTS" class GenerationFailedError(ComposerError): """Raised when max attempts exceeded.""" code = "GENERATION_FAILED" class EmptyInputError(ComposerError): """Raised when required input is empty.""" code = "EMPTY_INPUT" # === Response Builders === def success_response( data: Any, warnings: Optional[list[Warning]] = None, ) -> ApiResponse: """Build a successful API response.""" # Convert Pydantic models to dicts if needed if hasattr(data, "model_dump"): data = data.model_dump() return ApiResponse( success=True, data=data, warnings=warnings or [], ) def error_response(error: ComposerError | Exception) -> ApiResponse: """Build an error API response.""" if isinstance(error, ComposerError): error_detail = error.to_error_detail() else: error_detail = ErrorDetail( code="INTERNAL_ERROR", message=str(error), ) return ApiResponse( success=False, error=error_detail, ) def partial_success_response( data: Any, warnings: list[Warning], ) -> ApiResponse: """Build a partial success response with warnings.""" if hasattr(data, "model_dump"): data = data.model_dump() return ApiResponse( success=True, data=data, warnings=warnings, )

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/viktorkelemen/music21-composer-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server