solidworks_mcp.tools.error_classifier¶
solidworks_mcp.tools.error_classifier ¶
Classify tool failures into actionable error categories.
The MCP tool error boundary (tool_boundary) asks this module what kind of
failure it is looking at, so the payload can carry an error_type and a
hint telling the caller what to do next instead of an opaque message.
Adapter errors usually arrive as strings - _handle_com_operation flattens
COM exceptions to "COM error in <op>: (<hresult>, '<text>', ...)" - so every
rule can match on the message text, and COM rules also on the HRESULT taken
from either a com_error exception or that text.
Rules are evaluated in order; the first match wins. Add a category by appending a rule - callers never change.
Attributes¶
DEFAULT_RULES
module-attribute
¶
DEFAULT_RULES: tuple[ErrorRule, ...] = (ErrorRule(error_type='solidworks_unavailable', hint='SolidWorks is not reachable - it was closed or crashed. Restart SolidWorks (and the MCP server if it still fails), then retry.', hresults=frozenset({RPC_E_DISCONNECTED, RPC_S_SERVER_UNAVAILABLE, RPC_S_CALL_FAILED}), patterns=('rpc server is unavailable', 'object invoked has disconnected', 'not connected to solidworks', 'solidworks (application )?(is )?not connected', 'solidworks is not running')), ErrorRule(error_type='com_wrong_thread', hint='A SolidWorks call ran off the thread that connected - a server bug. Report the tool name; restart the MCP server to recover.', patterns=('belong to the thread that called connect',)), ErrorRule(error_type='circuit_open', hint='Calls to this operation are paused after repeated failures. Fix the underlying error, then call `reset_circuit_breaker` (or wait for the breaker timeout, SOLIDWORKS_MCP_CIRCUIT_BREAKER_TIMEOUT seconds) and retry.', patterns=('circuit breaker is (open|half[_-]open)',)), ErrorRule(error_type='com_member_not_found', hint='SolidWorks could not resolve this API member. Usually a server bug: a method called without being flagged as one (report the tool name). After a SolidWorks upgrade it can be a stale type cache: delete %TEMP%\\gen_py and restart the MCP server.', hresults=frozenset({DISP_E_MEMBERNOTFOUND}), patterns=('member not found',)), ErrorRule(error_type='com_type_mismatch', hint="SolidWorks rejected an argument's COM type. This is a server bug; report the tool name and arguments.", hresults=frozenset({DISP_E_TYPEMISMATCH}), patterns=('type mismatch',)), ErrorRule(error_type=NOT_SUPPORTED, hint=NOT_SUPPORTED_HINT, patterns=('does not support', 'no adapter capability', 'only available on windows', '\x08not available\x08')), ErrorRule(error_type='wrong_document_type', hint='The active document is the wrong kind for this tool. Create or activate the right one (create_part, create_assembly, create_drawing or activate_document), then retry.', patterns=('(requires|needs) an? (active )?(part|assembly|drawing)( or (part|assembly|drawing))? document',)), ErrorRule(error_type='no_active_sketch', hint='Create or open a sketch first (create_sketch), then retry.', patterns=('no active sketch',)), ErrorRule(error_type='no_active_document', hint='Open or create a document first (open_model / create_part), or activate one with activate_document, then retry.', patterns=('no active (model|document)',)), ErrorRule(error_type='feature_not_built', hint="SolidWorks accepted the call but the geometry gave it nothing to build. For a cut: the profile must be a closed loop that overlaps the solid within the depth; one-direction cuts already try both directions, so change the sketch, its plane, the depth or use end_condition 'ThroughAll' rather than retrying as is.", patterns=('built no feature',)), ErrorRule(error_type='not_found', hint='Check the name or path - list what exists first (list_features, list_open_documents, list_drawing_views) and use an exact name.', patterns=('\\bnot found\\b', 'does not exist', '\\bno such\\b', '\\bno [\\w.-]+( \\w+)? found\\b', '\\bhas no (\\w+ )?(edges|faces)\\b', '\\bhas no [\\w-]+ body\\b', '\\bno view named\\b')))
NOT_SUPPORTED_HINT
module-attribute
¶
NOT_SUPPORTED_HINT = 'The active adapter cannot perform this operation. Use the real SolidWorks adapter, another tool, or do this step in SolidWorks directly.'
_FALLBACK_HINTS
module-attribute
¶
_FALLBACK_HINTS = {OPERATION_FAILED: 'The SolidWorks operation failed. Read the message for the cause, adjust the inputs, and retry.', INTERNAL: 'Unexpected server error - this is a bug, not a modelling problem. Report the tool name, arguments and this message.'}
Classes¶
Classification
dataclass
¶
The category of a failure and the next step to suggest.
ErrorClassifier ¶
Map a failure to a :class:Classification using ordered rules.
Source code in src/solidworks_mcp/tools/error_classifier.py
Methods:¶
classify ¶
classify(message: str, exc: BaseException | None = None, *, fallback: str = OPERATION_FAILED) -> Classification
Classify message (and exc when there is one).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
message
|
str
|
The error text the caller will see. |
required |
exc
|
BaseException | None
|
The exception, when the failure was raised rather than returned. |
None
|
fallback
|
str
|
Category for an unrecognised failure: |
OPERATION_FAILED
|
Returns:
| Name | Type | Description |
|---|---|---|
Classification |
Classification
|
The first matching rule, else the fallback. |
Source code in src/solidworks_mcp/tools/error_classifier.py
ErrorRule
dataclass
¶
ErrorRule(error_type: str, hint: str, hresults: frozenset[int] = frozenset(), patterns: tuple[str, ...] = ())
Functions:¶
extract_hresult ¶
Return the COM HRESULT from a com_error or from flattened text.