Skip to content
CrossFly is 100% open sourceFollow us on GitHub
CrossFlyCrossFly
Get started

This page was machine-translated from Portuguese and may contain errors. The Portuguese version is canonical.

Error handling and logging

The central point is having a single funnel for exceptions and separating “an error the user sees” from “an error for the log”.

The funnel: Debug.handle(e) and Debug.log(...)

try {
   arriscado();
} catch (Exception e) {
   Debug.handle(e);        // logs and handles it uniformly (single funnel)
}
Debug.log("estado:", valor);   // free-form diagnostics

Framework animations and tasks already catch Throwable via Debug.handle internally. Why a funnel: an unhandled exception on the paint thread takes down the frame — channeling it avoids a crash and gives a single point to instrument.

React to specific errors (don’t swallow everything)

try (SqliteDb db = SqliteDb.open("app.db")) {
   db.execute("INSERT INTO cliente(email) VALUES(?)", email);
} catch (SqliteException e) {
   if (e.code == Sqlite.CONSTRAINT) Hint.show("E-mail já cadastrado", 2000);   // 19
   else if (e.code == Sqlite.BUSY)  Hint.show("Banco ocupado, tente de novo", 2000);  // 5
   else Debug.handle(e);
}

SqliteException.code carries the SQLite code (Sqlite.OK/BUSY/CONSTRAINT/LOCKED/...). The same applies to other typed results (e.g., AuthResult.ERROR from biometrics).

Errors from background callbacks → show in the UI with onUI

Callbacks (network, GPS, BLE) run outside the paint thread. To notify the user, marshal with onUI:

new Thread(() -> {
   try { sincronizar(); }
   catch (Exception e) {
      Component.onUI(() -> Hint.show("Falha ao sincronizar", 2000));   // Hint = non-blocking
      Debug.handle(e);
   }
}).start();
  • Hint.show(...) for non-blocking notices; Alert when it requires a user decision.
  • Separate: what the user needs to see (Hint/Alert) vs. what goes only to the log (Debug.log/handle).

Debug flags

Debug.traceKeyboard, Debug.showFPS, Debug.beepOnGC help diagnose during development.

Best practices

  • One funnel (Debug.handle) for what isn’t specifically handleable.
  • Handle specific codes (CONSTRAINT, BUSY) with a message useful to the user.
  • Background error → onUI + Hint/Alert; never touch the UI directly in the callback.

Common mistakes

  • Empty catch (Exception e) {} — swallows the problem.
  • Showing a raw stack trace to the user (use Hint/Alert with a clear message; the stack goes to the log).
  • Touching the UI from a background thread without onUI.

See also

Was this page helpful?