refactor: pull validateConnection / validateModelName / error mapping into base

Form Template Method / Pull Up Method from the Refactoring Guru catalog.

The three SDK-based providers (Claude, OpenAI, Gemini) each had their own
near-identical implementations of:

  - validateConnection: try a tiny request, catch errors, map a handful
    of patterns, warn on the rest
  - validateModelName: iterate regex patterns, warn on no match
  - handle{X}Error: switch on HTTP status, map to AIProviderError with
    brand-flavored messages

These collapse into three protected hooks on BaseAIProvider:

  - getModelNamePatterns(): RegExp[]
  - sendValidationProbe(): Promise<void>
  - mapProviderError(error): AIProviderError | null
  - providerErrorMessages(): Partial<Record<number, string>>

The base owns the wrapping logic (warning, status -> error-type map,
common message patterns). Providers only contribute their unique parts.

Side effects:

  - normalizeError now consults mapProviderError before generic mapping,
    so provider-specific patterns work via the existing try/catch in
    BaseAIProvider.complete/stream. The per-provider try/catch wrappers
    around doComplete/doStream are removed.
  - The unknown-error message becomes `${providerName} error: ${msg}`
    instead of the hardcoded `Provider error:` / `Claude API error:` etc.
  - OpenWebUI's HTTP-based validateConnection is preserved (override),
    since its non-SDK shape doesn't fit the SDK probe pattern.
This commit is contained in:
2026-05-21 13:43:07 +02:00
parent 8e73296ac2
commit b36d57711b
5 changed files with 352 additions and 717 deletions

View File

@@ -381,7 +381,7 @@ export class OpenWebUIProvider extends BaseAIProvider {
* @private
* @throws {AIProviderError} If connection validation fails
*/
private async validateConnection(): Promise<void> {
protected override async validateConnection(): Promise<void> {
try {
// Try to fetch available models to test connectivity
const url = this.useOllamaProxy