Merge pull request #910 from avisikta17pal/feature/logging-validation-console

fix(logging): redirect request validation warnings & errors to in-app console (#906, #587)
This commit is contained in:
Ankit Mahato
2025-11-17 06:31:01 +05:30
committed by GitHub
7 changed files with 52 additions and 12 deletions

View File

@@ -14,7 +14,6 @@ void main() async {
await Stac.initialize(); await Stac.initialize();
//Load all LLMs //Load all LLMs
// await LLMManager.fetchAvailableLLMs();
await ModelManager.fetchAvailableModels(); await ModelManager.fetchAvailableModels();
var settingsModel = await getSettingsFromSharedPrefs(); var settingsModel = await getSettingsFromSharedPrefs();
@@ -30,9 +29,6 @@ void main() async {
settingsModel = settingsModel?.copyWithPath(workspaceFolderPath: null); settingsModel = settingsModel?.copyWithPath(workspaceFolderPath: null);
} }
// TODO: Load all models at init
// await ModelManager.loadAvailableLLMs();
runApp( runApp(
ProviderScope( ProviderScope(
overrides: [ overrides: [

View File

@@ -350,8 +350,20 @@ class CollectionStateNotifier
executionRequestModel.httpRequestModel!); executionRequestModel.httpRequestModel!);
} }
// Terminal: start network log // Terminal
final terminal = ref.read(terminalStateProvider.notifier); final terminal = ref.read(terminalStateProvider.notifier);
var valRes = getValidationResult(substitutedHttpRequestModel);
if (valRes != null) {
terminal.logSystem(
category: 'validation',
message: valRes,
level: TerminalLevel.error,
);
ref.read(showTerminalBadgeProvider.notifier).state = true;
}
// Terminal: start network log
final logId = terminal.startNetwork( final logId = terminal.startNetwork(
apiType: executionRequestModel.apiType, apiType: executionRequestModel.apiType,
method: substitutedHttpRequestModel.method, method: substitutedHttpRequestModel.method,

View File

@@ -13,6 +13,7 @@ final historyCodePaneVisibleStateProvider = StateProvider<bool>((ref) => false);
final saveDataStateProvider = StateProvider<bool>((ref) => false); final saveDataStateProvider = StateProvider<bool>((ref) => false);
final clearDataStateProvider = StateProvider<bool>((ref) => false); final clearDataStateProvider = StateProvider<bool>((ref) => false);
final hasUnsavedChangesProvider = StateProvider<bool>((ref) => false); final hasUnsavedChangesProvider = StateProvider<bool>((ref) => false);
final showTerminalBadgeProvider = StateProvider<bool>((ref) => false);
// final nameTextFieldControllerProvider = // final nameTextFieldControllerProvider =
// StateProvider.autoDispose<TextEditingController>((ref) { // StateProvider.autoDispose<TextEditingController>((ref) {

View File

@@ -76,13 +76,21 @@ class Dashboard extends ConsumerWidget {
style: Theme.of(context).textTheme.labelSmall, style: Theme.of(context).textTheme.labelSmall,
), ),
kVSpacer10, kVSpacer10,
IconButton( Badge(
isSelected: railIdx == 3, backgroundColor: Theme.of(context).colorScheme.error,
onPressed: () { isLabelVisible:
ref.read(navRailIndexStateProvider.notifier).state = 3; ref.watch(showTerminalBadgeProvider) && railIdx != 3,
}, child: IconButton(
icon: const Icon(Icons.terminal_outlined), isSelected: railIdx == 3,
selectedIcon: const Icon(Icons.terminal), onPressed: () {
ref.read(navRailIndexStateProvider.notifier).state =
3;
ref.read(showTerminalBadgeProvider.notifier).state =
false;
},
icon: const Icon(Icons.terminal_outlined),
selectedIcon: const Icon(Icons.terminal),
),
), ),
Text( Text(
'Logs', 'Logs',

View File

@@ -8,4 +8,5 @@ export 'http_utils.dart';
export 'js_utils.dart'; export 'js_utils.dart';
export 'save_utils.dart'; export 'save_utils.dart';
export 'ui_utils.dart'; export 'ui_utils.dart';
export 'validation_utils.dart';
export 'window_utils.dart'; export 'window_utils.dart';

View File

@@ -0,0 +1,18 @@
import 'package:apidash_core/apidash_core.dart';
String? getValidationResult(HttpRequestModel requestModel) {
if (requestModel.url.trim().isEmpty) {
return 'Request URL is empty. Please provide a valid URL.';
}
if (requestModel.method == HTTPVerb.get && requestModel.hasAnyBody) {
return 'GET request contains a body. This is not supported.';
}
if (requestModel.hasJsonData) {
try {
kJsonDecoder.convert(requestModel.body!);
} catch (e) {
return 'Invalid JSON in request body: ${e.toString()}';
}
}
return null;
}

View File

@@ -47,6 +47,10 @@ class HttpRequestModel with _$HttpRequestModel {
bool get hasTextContentType => bodyContentType == ContentType.text; bool get hasTextContentType => bodyContentType == ContentType.text;
int get contentLength => utf8.encode(body ?? "").length; int get contentLength => utf8.encode(body ?? "").length;
bool get hasBody => hasJsonData || hasTextData || hasFormData; bool get hasBody => hasJsonData || hasTextData || hasFormData;
bool get hasAnyBody =>
(hasJsonContentType && contentLength > 0) ||
(hasTextContentType && contentLength > 0) ||
(hasFormDataContentType && formDataMapList.isNotEmpty);
bool get hasJsonData => bool get hasJsonData =>
kMethodsWithBody.contains(method) && kMethodsWithBody.contains(method) &&
hasJsonContentType && hasJsonContentType &&