Error Logging for Ionic 2 with Sentry (Raven.js)

Sentry is a realtime, platform-agnostic error logging and aggregation platform, that helps me catch errors across different projects. Raven.js is Sentry’s official browser JavaScript client and supports „quite a few“ technologies and frameworks (like plain-old JavaScript, Node.js: Express, Koa, Connect, Angular.js 1, Angular, Ember, React, Vue,…).

Ionic 2 comes with an excellent Error-Handling by default. It simply smashes all exceptions right into the developer’s face (the „React approach“ to handle things). This in itself is alright for development, but in production you should probably log all exceptions with solutions like Sentry.

To log exceptions with Sentry on Ionic 2, I decided to extend the existing IonicErrorHandler to additionally forward the logs to Sentry. The snippet below gives an example:

import * as Raven from 'raven-js';
import {NgModule, ErrorHandler} from '@angular/core';
import {IonicApp, IonicModule, IonicErrorHandler} from 'ionic-angular';
import {MyApp} from './app.component';
import {FoobarPage} from '../pages/home/home';

Raven
  .config('*YOUR DSN*')
  .install();

class RavenErrorHandler extends IonicErrorHandler implements ErrorHandler {
  handleError(err: any): void {
    super.handleError(err)
    Raven.captureException(err.originalError);
  }
}

@NgModule({
  declarations: [MyApp, FoobarPage],
  imports: [
    IonicModule.forRoot(MyApp)
  ],
  bootstrap: [IonicApp],
  entryComponents: [MyApp, FoobarPage],
  providers: [{provide: ErrorHandler, useClass: RavenErrorHandler}]
})
export class AppModule {}

Python Pillow 3 with Alpine Linux

Using Alpine Linux as a base for Docker images does have some implications and odd bugs. Trying to get Taiga (Backend) running with Alpine Linux I stumbled upon the following error log:

ValueError: --enable-zlib requested but zlib not found, aborting.

Even explicitly installing zlib (as required) does not help getting rid of the issue:

apk add --no-cache zlib zlib-dev

To get it working / recognizing the system’s zlib you need to

  • extend the CFLAGS environmental variable
CFLAGS="$CFLAGS -L/lib"
  • or create a softlink for the zlib library before executing the Pillow installation:
ln -s /lib/libz.so /usr/lib/

Further References:

ERROR ITMS-90071: CodeResources file must be a symbolic link

Using a continuous integration solution to efficiently develop iOS applications, I stumble upon the following issue when trying to upload an .ipa file using Apple’s Application Loader (Version 3.0)

ERROR ITMS-90071: “This bundle is invalid. The CodeResources file must be a symbolic link to _CodeSignature/CodeResources. Make certain that the bundle is on a locally-mounted volume [not a remote SMB volume], and be certain to use the Mac OS X Finder to compress it.”

The error might be caused by the way your CI solution creates your resulting archive or just due to running the build process from a command line instead of old-fashioned XCode with GUI.

To fix this issue you need to manually change the structure of your application file.

# extract your application archive file (ends with .ipa)
unzip Foobar.ipa -d tmp/

# change to the application folder (ends with .app)
cd tmp/Payload/Foobar.app

# overwrite or create the mentioned symbolic link
ln -fs _CodeSignature/CodeResources CodeResources

# change to the tmp/ folder
cd ../..

# recreate the application archive file (.ipa)
zip -yr9 Foobar.ipa Payload/

You should then be able to successfully upload your iOS application with Apple’s gorgeous Application Loader.

You can also use the copy’n’pastable example below (resulting file is called Fixed.ipa).

unzip *.ipa -d tmp/
cd tmp/Payload/*.app
ln -fs _CodeSignature/CodeResources CodeResources
cd ../..
zip -yr9 Fixed.ipa Payload/
cd ..
mv tmp/Fixed.ipa .
rm -r tmp
ls -lah

WordPress API v2 with Polylang and ACF

Using WordPress with Custom Post Types enriched with Advanced Custom Fields offers a simple solution to provide an intuitive Database management solution. With WP REST API v2 it’s even possible to use WordPress as a simple mobile backend. ACF to WP-API allows accessing the ACF attributes.
But using WP REST API v2 with ACF (through ACF to WP-API) does not work by default if you add Multilanguage support through Polylang. Even though you can filter post types through the filter parameter (e.g. filter[lang]=de) the ACF attributes are not resolved properly (AFAICT this only affects relationship fields).

Fortunately there are some smart folks out there that already figured out how to set the language for REST requests:

<?php
function polylang_json_api_init() {
  global $polylang;

  $default = pll_default_language();
  $langs = pll_languages_list();

  $cur_lang = $_GET['lang'];

  if (!in_array($cur_lang, $langs)) {
    $cur_lang = $default;
  }

  $polylang->curlang = $polylang->model->get_language($cur_lang);
  $GLOBALS['text_direction'] = $polylang->curlang->is_rtl ? 'rtl' : 'ltr';
}

add_action('rest_api_init', 'polylang_json_api_init');
?>

ADB over network with Android 2.3

For testing purposes I use an old Android 2.3 device that runs an old version of Cyanogenmod. Unfortunately I could not find an option to enable ADB over network in the device’s settings. I am not a fan of plugging in the device every time I would like to debug an application. But, fortunately, there is a way to enable ADB over network via Terminal if your device is rooted:

su
setprop service.adb.tcp.port 5555
stop adbd
start adbd

Afterwards you can connect as usual by running adb connect device-ip on your development machine.

To disable ADB over network you can set the TCP port option to -1:

setprop service.adb.tcp.port -1
stop adbd
start adbd

Cordova 5: Building signed Android applications

Even though signing Android applications is quite simpler than signing iOS applications, it’s sometimes annoying to set it up and reliably automate it (without using Phonegap or comparable services). Recently I tried automating singing a Cordova application for Android and struggled finding a reliable documentation.

The official Cordova documentation states, that you can easily append a bunch of arguments to the build command to automatically sign your Android application:

Keystore (--keystore): Path to a binary file which can hold a set of keys.
Keystore password (--storePassword): Password to the keystore
Alias (--alias): The id specifying the private key used for singing.
Password (--password): Password for the private key specified.
Type of the keystore (--keystoreType): pkcs12, jks (Default: auto-detect based on file extension)

The catch is, you need to append these arguments as platformopts (POPTS):

cordova build [PROD] [TARGET] [EXP] [PLATS] [BUILDCONFIG] [-- POPTS]

  PROD:   --debug|--release
  TARGET: --device|--emulator|--target=FOO
  EXP:    --experimental [EXPERIMENTALFLAGS]
  PLATS:  PLATFORM [...]
  BUILDCONFIG: --buildConfig=CONFIGFILE
  POPTS:  platformopts

Therefore the command to build a signed Cordova android application becomes:

cordova build --release android -- --keystore=my.keystore --storePassword=K3ySt0reP4ssw0rd --alias=foobar --password=K3yP4ssw0rd

Alternatively, you could specify them in a build configuration file (build.json) using (–buildConfig) argument.

{
     "android": {
         "release": {
             "keystore": "my.keystore",
             "storePassword": "K3ySt0reP4ssw0rd",
             "alias": "foobar",
             "password" : "K3yP4ssw0rd",
             "keystoreType": ""
         }
     }
 }

and respectively

cordova build --release android --buildConfig=buildConfig.json

I tested all those commands with Cordova 5.4.0

Android: Resize screen for dead touch zone

Unfortunately I recently stumbled upon hardware issues with my OnePlus One. About 1 inch (2,5 cm) of the display and the soft buttons stopped working suddenly. The display itself is fully intact, but it does not respond to any touch events or gestures anymore. As this leaves the device unusable for most interactions, I desperately searched for a solution on how to disable the defect part of the display. Especially as interaction with the on-screen nav bar is not possible due to the unresponsive 1 inch (2,5cm) high display part. So I basically had to find a way how to “push” the on-screen nav bar up a bit.

Continue reading →

Docker: Error opening terminal: unknown.

Executing bash in a running Docker container via docker exec -it [container] bash intending to edit a file with nano (or any other of those spiffy editors) might result in bash refusing to do its job.

Error opening terminal: unknown.

Thankfully there are some smart folks out there, who traced the TERM variable as the underlying troublemaker. Therefore assigning xterm as the variable’s value resolves the complications:

export TERM=xterm

dompdf: Explicit page break via CSS (page-break-*)

Switching from TCPDF to dompdf – due to image rendering / scaling / quality difficulties with TCPDF – I (unsurprisingly) stumbled upon some differences how dompdf handles the provided HTML. One of which is the way explicit page breaks can be accomplished. TCPDF expects you to use a special pagebreak attribute:

Whereas dompdf pays attention to the page-break-* CSS properties. A TCPDF-style replacement for an explicit page break might look like this: