Menu

Debugging and Getting Unstuck

Why is Debugging Important?

While Astro has many concepts you need to learn, knowing how to debug problems will greatly speed up your development time and also help you get a better idea of what’s going on (especially if things go wrong!).

Because Astro leverages web and native code, it can present some challenges to app developers because they need to debug code in two places: Xcode for native code and Safari/Chrome for JavaScript. This document points out some features of Astro to make this easier and presents some tips and tricks that the Astro team has found useful over time.

You can debug any web content in your Astro app (including the app.js' code, also known as the worker), by attaching the platform's browser to the web view you want to debug. On iOS use Safari, on Android use Google Chrome (note that these are the desktop browsers, not Mobile Safari or Mobile Chrome).

image alt text

Figure 1. You can inspect web content inside your app by using Safari.

Debugging app.js

For all Astro apps there is a special web view that runs your application JavaScript. It is known as "the worker" and is called app.js. The file that hosts the worker is always named index.html. To debug your application JavaScript, connect to this and you will see all of your application JavaScript (it will be a single, concatenated file and not separate files as they are when you are developing them). It is always named app.js. Many websites also name pages index.html, so you may need to find the right one when attaching a web view inspector. You will know you found the right index.html when the list of scripts includes app.js.

In the illustration below you’ll see there are two index.html files. One that’s hosting app.js (highlighted in Figure 2 below) and another that’s serving our website from localhost.

image alt text

Figure 2. You can debug app.js by inspecting index.html

Inspecting Web Content in iOS

You can inspect and debug live HTML content on your iOS device from your development machine. The Safari Web Inspector Guide provides steps to attach desktop Safari to an iOS application's web views.

To enable Web Inspector for iOS:

  1. Open Safari and from the menu:

    1. Choose Safari > Preferences > Advanced.

    2. Enable the "Show Develop menu in menu bar" setting found in Safari’s preferences under the Advanced pane.

You should now see a Develop command available to you in Safari’s toolbar at the top of your screen (see Figure 2 above).

image alt text

Figure 3. The Advanced pane of Safari’s preferences.

If you’re running your app in the simulator, you can inspect the web content:

  1. Choose Safari > Develop > Simulator > [name of the url to inspect].

Inspecting Web Content in Android

Debugging a web view in Android is very similar to that of iOS. Instead of using Safari, you use Chrome to inspect your web content. Android web view debugging works best with a real phone (as opposed to using a simulator). There is documentation you can follow to learn how to attach desktop Google Chrome to an Android application's web views.

image alt text

Figure 4. Chrome allows you to inspect web content in your Android app.

Typical Debug Steps

Bugs can appear in different places in your code and can manifest in different ways. We’ve distilled the debug process down to three steps that should follow to help you identify the common bugs in your application.

  1. When you load the app, but it does it not start properly.

    1. aka. the "White Screen of Death" because this typically results in your application showing a blank/white HTML document.

    2. Typically, this is due to a problem in app.js (eg.: calling a function that throws an error), so start by inspecting index.html using the web view inspectors mentioned above.

    3. When inspecting app.js, run Astro.loggedErrors(), to see an output of any errors that might have occurred.

    4. Finally, resolve the error that’s outputted after Astro.loggedErrors()

  2. If the app is started, but something is not working in a web view.

    1. Open the web view in Chrome (normally, without the device inspector) and see if there are any outputted errors. Perhaps you mistyped something?

    2. If not, inspect your web view in the device (using Safari for iOS or Chrome for Android) and run Astro.loggedErrors() in that web view to get an output of the errors that might have occurred in that web view

    3. Finally, if there are no errors, check index.html (using the device inspector) and see if there are any errors in app.js

  3. Finally, if neither of the above methods help you find the error, then you may have an error in the native code.

    1. Open Xcode or Android Studio and check the console output. It should appear automatically when there is native error. The error description should help guide you to an answer.

Logging Errors

Errors in the JavaScript code of an Astro app can be hard to diagnose. Safari doesn't help things because it doesn't show any console messages that were posted prior to attaching to a web view instance. To mitigate this, Astro provides a method that you can call in the Safari developer console to show errors that were posted up to that point. Simply call this from your web view to see all previous JavaScript errors:

Astro.loggedErrors()

This will print all captured errors to the JavaScript console.

Another useful trick is to wrap app.js in a method called window.run. At the bottom of app.js we simply call the run method. To debug really nasty problems (especially related to bootstrapping) we can comment out the run method, attach the debugger, and then call window.run() in the debugger console. That gives us a view of all errors as they occur.

window.run = function() {
    // Astro bootstrap code
}

// Comment out next line for JS debugging
window.run()

Compiler Flags

At times it is useful to use compiler flags to conditionally run some code in one build configuration, but not any other. While this is a slightly advanced topic, you’ll almost always need to do this before releasing an app to the App Store in order to test features in a production mode (example: pointing a development version of the app to a staging server instead of the production server). Astro includes two compiler flags: DEBUG and RELEASE to allow only running code in a development (DEBUG) or release (RELEASE) build.

To add a compiler flag to an Xcode project:

  1. Open the Project view.

  2. Choose the main app target (typically named the same as your project) and choose Build Settings.

  3. Find the section Swift Compiler - Custom Flags.

  4. Expand the Other Swift Flags entry and choose the Debug row. Once chosen wait a second and then click in the right column to begin editing the flag. Type in the new flag value prefixed with "-D" (eg. "-D DEBUG") and choose .

Android Studio automatically provides a similar feature through the BuildConfig.DEBUG boolean. You can use it in a regular to conditionally execute (or not) some code. Using the Compiler Flag you can now write the following native code to conditionally compile in DEBUG and RELEASE builds:

Swift (iOS):

#if DEBUG
println("We're in a debug build.")
#elseif RELEASE
println("We're in a release build.")
#endif

Java (Android):

if (BuildConfig.DEBUG) {
    Log.d(TAG, "We're in a debug build.");
} else {
    Log.d(TAG, "We're in a release build.");
}

NOTE: Use of conditional code should be kept to a minimum. It is really easy to write some code in one conditional but forget about the others and leave the code in a broken state.

Summary

Debugging is crucial for understanding any new language or framework. Because you might still be new to Astro you’re bound to make mistakes or encounter bugs. Being able to look around an application and investigate the cause of your bug is not only going to help you get unstuck but also help you get a better understanding of how Astro works.

Because Astro mixes both web and native elements it’s important to understand the interplay between them in order to know where to debug your application. Errors can occur in three common places: the app.js web view (called index.html), web views that you’re hosting yourself or in native code. Finally, you should know when and how to use Astro’s built in logger so that you can see previously logged errors and so that you can output your own error messages to make debugging easier.