diff --git a/frontend/lib/services/chat_service.dart b/frontend/lib/services/chat_service.dart index a24aec4ff..b051d1812 100644 --- a/frontend/lib/services/chat_service.dart +++ b/frontend/lib/services/chat_service.dart @@ -20,7 +20,8 @@ class ChatService { return await api.post( 'agent/tasks/$taskId/steps', stepRequestBody.toJson()); } catch (e) { - throw Exception('Failed to execute step: $e'); + // TODO: We are bubbling up the full response. Revisit this. + rethrow; } } diff --git a/frontend/lib/services/task_service.dart b/frontend/lib/services/task_service.dart index 2fe77dccf..da7316f37 100644 --- a/frontend/lib/services/task_service.dart +++ b/frontend/lib/services/task_service.dart @@ -19,7 +19,8 @@ class TaskService { try { return await api.post('agent/tasks', taskRequestBody.toJson()); } catch (e) { - throw Exception('Failed to create a new task: $e'); + // TODO: We are bubbling up the full response. Revisit this. + rethrow; } } diff --git a/frontend/lib/utils/rest_api_utility.dart b/frontend/lib/utils/rest_api_utility.dart index 889fa7f4d..ab83ddfa5 100644 --- a/frontend/lib/utils/rest_api_utility.dart +++ b/frontend/lib/utils/rest_api_utility.dart @@ -50,7 +50,9 @@ class RestApiUtility { if (response.statusCode == 200 || response.statusCode == 201) { return json.decode(response.body); } else { - throw Exception('Failed to post data'); + // TODO: We are bubbling up the full response to show better errors on the UI. + // Let's put some thought into how we would like to structure this. + throw response; } } @@ -66,8 +68,6 @@ class RestApiUtility { if (response.statusCode == 200 || response.statusCode == 201) { return json.decode(response.body); } else { - print(response.statusCode); - print(response.body); throw Exception('Failed to update data with PUT request'); } } diff --git a/frontend/lib/viewmodels/chat_viewmodel.dart b/frontend/lib/viewmodels/chat_viewmodel.dart index c33d827f2..3dfec1dee 100644 --- a/frontend/lib/viewmodels/chat_viewmodel.dart +++ b/frontend/lib/viewmodels/chat_viewmodel.dart @@ -166,9 +166,9 @@ class ChatViewModel with ChangeNotifier { } print("Chats added for task ID: $_currentTaskId"); - } catch (error) { - // TODO: Bubble up errors to UI - print("Error sending chat: $error"); + } catch (e) { + // TODO: We are bubbling up the full response. Revisit this. + rethrow; // TODO: Handle additional error scenarios or log them as required } finally { _isWaitingForAgentResponse = false; diff --git a/frontend/lib/viewmodels/task_viewmodel.dart b/frontend/lib/viewmodels/task_viewmodel.dart index c5a89f2b9..7bb8f6899 100644 --- a/frontend/lib/viewmodels/task_viewmodel.dart +++ b/frontend/lib/viewmodels/task_viewmodel.dart @@ -26,19 +26,24 @@ class TaskViewModel with ChangeNotifier { /// Adds a task and returns its ID. Future createTask(String title) async { - final newTask = TaskRequestBody(input: title); - // Add to data source - final createdTask = await _taskService.createTask(newTask); - // Create a Task object from the created task response - final newTaskObject = - Task(id: createdTask['task_id'], title: createdTask['input']); + try { + final newTask = TaskRequestBody(input: title); + // Add to data source + final createdTask = await _taskService.createTask(newTask); + // Create a Task object from the created task response + final newTaskObject = + Task(id: createdTask['task_id'], title: createdTask['input']); - fetchAndCombineData(); + fetchAndCombineData(); - final taskId = newTaskObject.id; - print("Task $taskId created successfully!"); + final taskId = newTaskObject.id; + print("Task $taskId created successfully!"); - return newTaskObject.id; // Return the ID of the new task + return newTaskObject.id; + } catch (e) { + // TODO: We are bubbling up the full response. Revisit this. + rethrow; + } } /// Deletes a task. diff --git a/frontend/lib/views/chat/chat_view.dart b/frontend/lib/views/chat/chat_view.dart index 8c4aa8a4a..596d64f7f 100644 --- a/frontend/lib/views/chat/chat_view.dart +++ b/frontend/lib/views/chat/chat_view.dart @@ -8,7 +8,9 @@ import 'package:auto_gpt_flutter_client/views/chat/loading_indicator.dart'; import 'package:auto_gpt_flutter_client/views/chat/user_message_tile.dart'; import 'package:flutter/material.dart'; import 'package:auto_gpt_flutter_client/viewmodels/chat_viewmodel.dart'; +import 'package:fluttertoast/fluttertoast.dart'; import 'package:provider/provider.dart'; +import 'package:http/http.dart' as http; class ChatView extends StatefulWidget { final ChatViewModel viewModel; @@ -118,20 +120,39 @@ class _ChatViewState extends State { padding: const EdgeInsets.all(8.0), child: ChatInputField( onSendPressed: (message) async { - if (widget.viewModel.currentTaskId != null) { - widget.viewModel.sendChatMessage( - (message == "") ? null : message, - continuousModeSteps: - Provider.of(context, listen: false) - .continuousModeSteps); - } else { - String newTaskId = await taskViewModel.createTask(message); - widget.viewModel.setCurrentTaskId(newTaskId); - widget.viewModel.sendChatMessage( - (message == "") ? null : message, - continuousModeSteps: - Provider.of(context, listen: false) - .continuousModeSteps); + try { + if (widget.viewModel.currentTaskId != null) { + widget.viewModel.sendChatMessage( + (message == "") ? null : message, + continuousModeSteps: Provider.of( + context, + listen: false) + .continuousModeSteps); + } else { + String newTaskId = await taskViewModel.createTask(message); + widget.viewModel.setCurrentTaskId(newTaskId); + widget.viewModel.sendChatMessage( + (message == "") ? null : message, + continuousModeSteps: Provider.of( + context, + listen: false) + .continuousModeSteps); + } + } catch (response) { + if (response is http.Response && response.statusCode == 404) { + Fluttertoast.showToast( + msg: + "404 error: Please ensure the correct baseURL for your agent in \nthe settings and that your agent adheres to the agent protocol.", + toastLength: Toast.LENGTH_LONG, + gravity: ToastGravity.TOP, + timeInSecForIosWeb: 5, + backgroundColor: Colors.red, + webPosition: "center", + webBgColor: + "linear-gradient(to right, #dc1c13, #dc1c13)", + textColor: Colors.white, + fontSize: 16.0); + } } }, onContinuousModePressed: () { diff --git a/frontend/pubspec.lock b/frontend/pubspec.lock index 33d60d70a..8b12578cc 100644 --- a/frontend/pubspec.lock +++ b/frontend/pubspec.lock @@ -192,6 +192,14 @@ packages: description: flutter source: sdk version: "0.0.0" + fluttertoast: + dependency: "direct main" + description: + name: fluttertoast + sha256: "474f7d506230897a3cd28c965ec21c5328ae5605fc9c400cd330e9e9d6ac175c" + url: "https://pub.dev" + source: hosted + version: "8.2.2" google_identity_services_web: dependency: transitive description: diff --git a/frontend/pubspec.yaml b/frontend/pubspec.yaml index a9af8d240..2b3f39ffa 100644 --- a/frontend/pubspec.yaml +++ b/frontend/pubspec.yaml @@ -46,6 +46,7 @@ dependencies: google_sign_in: ^6.1.5 uuid: ^4.0.0 url_launcher: ^6.1.14 + fluttertoast: ^8.2.2 dev_dependencies: flutter_test: