Merge pull request #169 from cogwheel0/improve-model-parsing-error-handling

feat(api): improve model parsing with robust error handling
This commit is contained in:
cogwheel
2025-11-24 17:54:04 +05:30
committed by GitHub

View File

@@ -339,17 +339,64 @@ class ApiService {
Future<List<Model>> getModels() async { Future<List<Model>> getModels() async {
final response = await _dio.get('/api/models'); final response = await _dio.get('/api/models');
// Handle different response formats // Normalize common response formats:
List<dynamic> models; // - {"data": [...]} (OpenAI)
if (response.data is Map && response.data['data'] != null) { // - {"models": [...]} (some proxies)
// Response is wrapped in a 'data' field // - [...] (raw array)
models = response.data['data'] as List; // - String payloads that need JSON decoding
} else if (response.data is List) { dynamic payload = response.data;
// Response is a direct array if (payload is String) {
models = response.data as List; try {
} else { payload = json.decode(payload);
DebugLogger.error('models-format', scope: 'api/models'); } catch (_) {}
return []; }
List<dynamic>? rawModels;
if (payload is Map && payload['data'] is List) {
rawModels = payload['data'] as List;
} else if (payload is Map && payload['models'] is List) {
rawModels = payload['models'] as List;
} else if (payload is List) {
rawModels = payload;
}
if (rawModels == null) {
DebugLogger.error(
'models-format',
scope: 'api/models',
data: {'type': payload.runtimeType},
);
return const [];
}
final models = <Model>[];
for (final raw in rawModels) {
try {
if (raw is String) {
models.add(Model(id: raw, name: raw, supportsStreaming: true));
continue;
}
if (raw is Map) {
final normalized = raw.map(
(key, value) => MapEntry(key.toString(), value),
);
models.add(Model.fromJson(normalized));
continue;
}
DebugLogger.warning(
'models-entry-unknown',
scope: 'api/models',
data: {'type': raw.runtimeType},
);
} catch (error, stackTrace) {
DebugLogger.error(
'model-parse-failed',
scope: 'api/models',
error: error,
stackTrace: stackTrace,
data: {'type': raw.runtimeType},
);
}
} }
DebugLogger.log( DebugLogger.log(
@@ -357,7 +404,7 @@ class ApiService {
scope: 'api/models', scope: 'api/models',
data: {'count': models.length}, data: {'count': models.length},
); );
return models.map((m) => Model.fromJson(m)).toList(); return models;
} }
// Get default model configuration from OpenWebUI user settings // Get default model configuration from OpenWebUI user settings