Skip to main content
Glama
errors.go3.38 kB
package mbta import ( "encoding/json" "fmt" "net/http" "time" ) // APIError represents an error returned by the MBTA API type APIError struct { StatusCode int Status string Code string Title string Detail string Source map[string]interface{} } // Error implements the error interface for APIError func (e *APIError) Error() string { return fmt.Sprintf("MBTA API Error (%s): %s - %s", e.Status, e.Title, e.Detail) } // IsNotFoundError checks if the error is a not found error func (e *APIError) IsNotFoundError() bool { return e.StatusCode == http.StatusNotFound } // IsAuthError checks if the error is an authentication error func (e *APIError) IsAuthError() bool { return e.StatusCode == http.StatusUnauthorized } // IsRateLimitError checks if the error is a rate limit error func (e *APIError) IsRateLimitError() bool { return e.StatusCode == http.StatusTooManyRequests } // RateLimitError is a specific type of error for rate limiting type RateLimitError struct { *APIError RetryAfter int // Seconds to wait before retrying } // Error implements the error interface for RateLimitError func (e *RateLimitError) Error() string { return fmt.Sprintf("MBTA API Rate Limit Exceeded: %s. Retry after %d seconds", e.Detail, e.RetryAfter) } // NetworkError represents a network-related error type NetworkError struct { Err error } // Error implements the error interface for NetworkError func (e *NetworkError) Error() string { return fmt.Sprintf("Network error: %v", e.Err) } // TimeoutError represents a timeout error type TimeoutError struct { *NetworkError Timeout time.Duration } // Error implements the error interface for TimeoutError func (e *TimeoutError) Error() string { return fmt.Sprintf("Request timed out after %v: %v", e.Timeout, e.Err) } // parseAPIError parses an error response from the MBTA API func parseAPIError(statusCode int, responseBody []byte) error { var errorResponse struct { Errors []struct { Status string `json:"status"` Code string `json:"code"` Title string `json:"title"` Detail string `json:"detail"` Source map[string]interface{} `json:"source,omitempty"` } `json:"errors"` } if err := json.Unmarshal(responseBody, &errorResponse); err != nil { // If we can't parse the error response, return a generic error return &APIError{ StatusCode: statusCode, Status: fmt.Sprintf("%d", statusCode), Title: http.StatusText(statusCode), Detail: string(responseBody), } } // If there are no errors in the response, return a generic error if len(errorResponse.Errors) == 0 { return &APIError{ StatusCode: statusCode, Status: fmt.Sprintf("%d", statusCode), Title: http.StatusText(statusCode), Detail: string(responseBody), } } // Get the first error apiErr := errorResponse.Errors[0] // Create the error err := &APIError{ StatusCode: statusCode, Status: apiErr.Status, Code: apiErr.Code, Title: apiErr.Title, Detail: apiErr.Detail, Source: apiErr.Source, } // Check for rate limit errors if statusCode == http.StatusTooManyRequests { // For now, default to 60 seconds if no retry-after header retryAfter := 60 return &RateLimitError{ APIError: err, RetryAfter: retryAfter, } } return err }

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/crdant/mbta-mcp-server'

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