diff --git a/frontend/.github/workflows/build_app_android.yaml b/frontend/.github/workflows/build_app_android.yaml
index 451cfbb..074e835 100644
--- a/frontend/.github/workflows/build_app_android.yaml
+++ b/frontend/.github/workflows/build_app_android.yaml
@@ -41,9 +41,8 @@ jobs:
 
       - name: Load secrets from github
         run: |
-          echo "${{ secrets.ANDROID_SECRET_PROPERTIES }}" > secrets.properties
-          echo "${{ secrets.ANDROID_GOOGLE_PLAY_JSON }}" > fastlane/google-key.json
-          # decode the base64 encoded google key
+          echo "${{ secrets.ANDROID_SECRET_PROPERTIES_BASE64 }}" | base64 -d > secrets.properties
+          echo "${{ secrets.ANDROID_GOOGLE_PLAY_JSON_BASE64 }}" | base64 -d > fastlane/google-key.json
           echo "${{ secrets.ANDROID_KEYSTORE_BASE64 }}" | base64 -d > release.keystore
         working-directory: android
 
diff --git a/frontend/lib/modules/current_trip_error_message.dart b/frontend/lib/modules/current_trip_error_message.dart
new file mode 100644
index 0000000..880da7a
--- /dev/null
+++ b/frontend/lib/modules/current_trip_error_message.dart
@@ -0,0 +1,37 @@
+import 'package:anyway/structs/trip.dart';
+import 'package:auto_size_text/auto_size_text.dart';
+import 'package:flutter/material.dart';
+
+class CurrentTripErrorMessage extends StatefulWidget {
+  final Trip trip;
+  const CurrentTripErrorMessage({
+    super.key,
+    required this.trip,
+  });
+
+  @override
+  State<CurrentTripErrorMessage> createState() => _CurrentTripErrorMessageState();
+}
+
+class _CurrentTripErrorMessageState extends State<CurrentTripErrorMessage> {
+  @override
+  Widget build(BuildContext context) => Center(
+    child: Row(
+      mainAxisAlignment: MainAxisAlignment.center,
+      children: [
+        const Icon(
+          Icons.error_outline,
+          color: Colors.red,
+          size: 50,
+        ),
+        const Padding(
+          padding: EdgeInsets.only(left: 10),
+        ),
+        AutoSizeText(
+          'Error: ${widget.trip.errorDescription}',
+          maxLines: 3,
+        ),
+      ],
+    )
+  );
+}
diff --git a/frontend/lib/modules/current_trip_greeter.dart b/frontend/lib/modules/current_trip_greeter.dart
index 6a2118a..7655b73 100644
--- a/frontend/lib/modules/current_trip_greeter.dart
+++ b/frontend/lib/modules/current_trip_greeter.dart
@@ -1,111 +1,50 @@
-import 'dart:developer';
-
-import 'package:anyway/constants.dart';
-import 'package:anyway/structs/trip.dart';
+import 'package:flutter/material.dart';
 import 'package:auto_size_text/auto_size_text.dart';
 
-import 'package:flutter/material.dart';
+import 'package:anyway/pages/current_trip.dart';
+import 'package:anyway/structs/trip.dart';
 
-class Greeter extends StatefulWidget {
+
+class CurrentTripGreeter extends StatefulWidget {
   final Trip trip;
 
-  Greeter({
+  CurrentTripGreeter({
+    super.key,
     required this.trip,
   });
 
   @override
-  State<Greeter> createState() => _GreeterState();
+  State<CurrentTripGreeter> createState() => _CurrentTripGreeterState();
 }
 
 
-class _GreeterState extends State<Greeter> {
-  
-  Widget greeterBuilder (BuildContext context, Widget? child) {
-    final Shader textGradient = APP_GRADIENT.createShader(Rect.fromLTWH(0.0, 0.0, 200.0, 70.0));
-    TextStyle greeterStyle = TextStyle(
-      foreground: Paint()..shader = textGradient,
-      fontWeight: FontWeight.bold,
-      fontSize: 26
-    );
-
-    Widget topGreeter;
-
-    if (widget.trip.uuid != 'pending') {
-      topGreeter = FutureBuilder(
-        future: widget.trip.cityName,
-        builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
-          if (snapshot.hasData) {
-            return AutoSizeText(
-              maxLines: 1,
-              'Welcome to ${snapshot.data}!',
-              style: greeterStyle
-            );
-          } else if (snapshot.hasError) {
-            log('Error while fetching city name');
-            return AutoSizeText(
-              maxLines: 1,
-              'Welcome to your trip!',
-              style: greeterStyle
-            );
-          } else {
-            return AutoSizeText(
-              maxLines: 1,
-              'Welcome to ...',
-              style: greeterStyle
-            );
-          }
-        }
-      );
-    } else {
-      // still awaiting the trip
-      // We can hopefully infer the city name from the cityName future
-      // Show a linear loader at the bottom and an info message above
-      topGreeter = Column(
-        mainAxisAlignment: MainAxisAlignment.end,
-        children: [
-          FutureBuilder(
-            future: widget.trip.cityName,
-            builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
-              if (snapshot.hasData) {
-                return AutoSizeText(
-                  maxLines: 1,
-                  'Generating your trip to ${snapshot.data}...',
-                  style: greeterStyle
-                );
-              } else if (snapshot.hasError) {
-                // the exact error is shown in the central part of the trip overview. No need to show it here
-                return AutoSizeText(
-                  maxLines: 1,
-                  'Error while loading trip.',
-                  style: greeterStyle
-                  );
-              }
-              return AutoSizeText(
-                  maxLines: 1,
-                  'Generating your trip...',
-                  style: greeterStyle
-                  );
-            }
-          ),
-          Padding(
-            padding: EdgeInsets.all(5),
-            child: const LinearProgressIndicator()
-          )
-        ]
-      );
-    }
-
-    return Center(
-      child: topGreeter,
-    );
-  }
-
-
+class _CurrentTripGreeterState extends State<CurrentTripGreeter> {
   @override
-  Widget build(BuildContext context) {
-    return ListenableBuilder(
-      listenable: widget.trip,
-      builder: greeterBuilder,
-    );
-  }
+  Widget build(BuildContext context) => Center(
+    child: FutureBuilder(
+      future: widget.trip.cityName,
+      builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
+        if (snapshot.hasData) {
+          return AutoSizeText(
+            maxLines: 1,
+            'Welcome to ${snapshot.data}!',
+            style: greeterStyle
+          );
+        } else if (snapshot.hasError) {
+          return AutoSizeText(
+            maxLines: 1,
+            'Welcome to your trip!',
+            style: greeterStyle
+          );
+        } else {
+          return AutoSizeText(
+            maxLines: 1,
+            'Welcome to ...',
+            style: greeterStyle
+          );
+        }
+      }
+    )
+  );
+
 }
\ No newline at end of file
diff --git a/frontend/lib/modules/current_trip_loading_indicator.dart b/frontend/lib/modules/current_trip_loading_indicator.dart
new file mode 100644
index 0000000..7d61b2a
--- /dev/null
+++ b/frontend/lib/modules/current_trip_loading_indicator.dart
@@ -0,0 +1,60 @@
+import 'package:flutter/material.dart';
+import 'package:auto_size_text/auto_size_text.dart';
+
+import 'package:anyway/structs/trip.dart';
+import 'package:anyway/pages/current_trip.dart';
+
+class CurrentTripLoadingIndicator extends StatefulWidget {
+  final Trip trip;
+  const CurrentTripLoadingIndicator({
+    super.key,
+    required this.trip,
+  });
+
+  @override
+  State<CurrentTripLoadingIndicator> createState() => _CurrentTripLoadingIndicatorState();
+}
+
+class _CurrentTripLoadingIndicatorState extends State<CurrentTripLoadingIndicator> {
+  @override
+  Widget build(BuildContext context) => Center(
+    child: FutureBuilder(
+      future: widget.trip.cityName,
+      builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
+        Widget greeter;
+        Widget loadingIndicator = const Padding(
+          padding: EdgeInsets.only(top: 10),
+          child: CircularProgressIndicator()
+        );
+
+        if (snapshot.hasData) {
+          greeter = AutoSizeText(
+            maxLines: 1,
+            'Generating your trip to ${snapshot.data}...',
+            style: greeterStyle,
+          );
+        } else if (snapshot.hasError) {
+          // the exact error is shown in the central part of the trip overview. No need to show it here
+          greeter = AutoSizeText(
+            maxLines: 1,
+            'Error while loading trip.',
+            style: greeterStyle,
+            );
+        } else {
+          greeter = AutoSizeText(
+            maxLines: 1,
+            'Generating your trip...',
+            style: greeterStyle,
+            );
+        }
+        return Column(
+          mainAxisAlignment: MainAxisAlignment.center,
+          children: [
+            greeter,
+            loadingIndicator,
+          ],
+        );
+      }
+    )
+  );
+}
\ No newline at end of file
diff --git a/frontend/lib/modules/current_trip_panel.dart b/frontend/lib/modules/current_trip_panel.dart
index cd73f28..45ecdcc 100644
--- a/frontend/lib/modules/current_trip_panel.dart
+++ b/frontend/lib/modules/current_trip_panel.dart
@@ -1,4 +1,6 @@
 import 'package:anyway/constants.dart';
+import 'package:anyway/modules/current_trip_error_message.dart';
+import 'package:anyway/modules/current_trip_loading_indicator.dart';
 import 'package:flutter/material.dart';
 
 import 'package:anyway/structs/trip.dart';
@@ -28,16 +30,36 @@ class _CurrentTripPanelState extends State<CurrentTripPanel> {
     return ListenableBuilder(
       listenable: widget.trip,
       builder: (context, child) {
-        if (widget.trip.uuid != 'pending' && widget.trip.uuid != 'error') {
+        if (widget.trip.uuid == 'error') {
+          return Align(
+              alignment: Alignment.topCenter,
+              child: SizedBox(
+                // reuse the exact same height as the panel has when collapsed
+                // this way the greeter will be centered when the panel is collapsed
+                height: MediaQuery.of(context).size.height * TRIP_PANEL_MIN_HEIGHT - 20,
+                child: CurrentTripErrorMessage(trip: widget.trip)
+              ),
+            );
+        } else if (widget.trip.uuid == 'pending') {
+            return Align(
+              alignment: Alignment.topCenter,
+              child: SizedBox(
+                // reuse the exact same height as the panel has when collapsed
+                // this way the greeter will be centered when the panel is collapsed
+                height: MediaQuery.of(context).size.height * TRIP_PANEL_MIN_HEIGHT - 20,
+                child: CurrentTripLoadingIndicator(trip: widget.trip),
+              ),
+            );
+        } else {
           return ListView(
             controller: widget.controller,
-            padding: const EdgeInsets.only(bottom: 30, left: 5, right: 5),
+            padding: const EdgeInsets.only(bottom: 30),
             children: [
               SizedBox(
                 // reuse the exact same height as the panel has when collapsed
                 // this way the greeter will be centered when the panel is collapsed
                 height: MediaQuery.of(context).size.height * TRIP_PANEL_MIN_HEIGHT - 20,
-                child: Greeter(trip: widget.trip),
+                child: CurrentTripGreeter(trip: widget.trip),
               ),
 
               const Padding(padding: EdgeInsets.only(top: 10)),
@@ -53,28 +75,6 @@ class _CurrentTripPanelState extends State<CurrentTripPanel> {
               Center(child: saveButton(widget.trip)),
             ],
           );
-        } else if(widget.trip.uuid == 'pending') {
-          return SizedBox(
-            // reuse the exact same height as the panel has when collapsed
-            // this way the greeter will be centered when the panel is collapsed
-            height: MediaQuery.of(context).size.height * TRIP_PANEL_MIN_HEIGHT - 20,
-            child: Greeter(trip: widget.trip)
-          );
-        } else {
-          return Row(
-            mainAxisAlignment: MainAxisAlignment.center,
-            children: [
-              const Icon(
-                Icons.error_outline,
-                color: Colors.red,
-                size: 50,
-              ),
-              Padding(
-                padding: const EdgeInsets.only(left: 10),
-                child: Text('Error: ${widget.trip.errorDescription}'),
-              ),
-            ],
-          );
         }
       }
     );
diff --git a/frontend/lib/pages/current_trip.dart b/frontend/lib/pages/current_trip.dart
index 834b3f6..8967f6c 100644
--- a/frontend/lib/pages/current_trip.dart
+++ b/frontend/lib/pages/current_trip.dart
@@ -6,6 +6,12 @@ import 'package:anyway/structs/trip.dart';
 import 'package:anyway/modules/current_trip_map.dart';
 import 'package:anyway/modules/current_trip_panel.dart';
 
+final Shader textGradient = APP_GRADIENT.createShader(Rect.fromLTWH(0.0, 0.0, 200.0, 70.0));
+TextStyle greeterStyle = TextStyle(
+  foreground: Paint()..shader = textGradient,
+  fontWeight: FontWeight.bold,
+  fontSize: 26
+);
 
 
 class TripPage extends StatefulWidget {
@@ -35,7 +41,7 @@ class _TripPageState extends State<TripPage> {
         maxHeight: MediaQuery.of(context).size.height * TRIP_PANEL_MAX_HEIGHT,
         // padding in this context is annoying: it offsets the notion of vertical alignment.
         // children that want to be centered vertically need to have their size adjusted by 2x the padding
-        padding: const EdgeInsets.only(top: 10),
+        padding: const EdgeInsets.all(10.0),
         // Panel snapping should not be disabled because it significantly improves the user experience
         // panelSnapping: false
         borderRadius: const BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)),
diff --git a/frontend/lib/utils/fetch_trip.dart b/frontend/lib/utils/fetch_trip.dart
index a497f2e..e6c1f2c 100644
--- a/frontend/lib/utils/fetch_trip.dart
+++ b/frontend/lib/utils/fetch_trip.dart
@@ -38,10 +38,18 @@ fetchTrip(
   String dataString = jsonEncode(data);
   log(dataString);
 
-  final response = await dio.post(
-    "/trip/new",
-    data: data
-  );
+  late Response response;
+  try {
+     response = await dio.post(
+      "/trip/new",
+      data: data
+    );
+  } catch (e) {
+    trip.updateUUID("error");
+    trip.updateError(e.toString());
+    log(e.toString());
+    return;
+  }
 
   // handle errors
   if (response.statusCode != 200) {