Application error events
Exception (error) tracking captures exceptions within your application.
This table shows the support for exception tracking across the main client-side Snowplow tracker SDKs. The server-side trackers don't include error tracking APIs.
| Tracker | Supported | Since version | Auto-tracking | Notes |
|---|---|---|---|---|
| Web | ✅ | 3.0.0 | ✅/❌ | Requires error tracking plugin. Track handled exceptions manually. |
| iOS | ✅ | 1.0.0 | ✅ | |
| Android | ✅ | 1.0.0 | ✅ | |
| React Native | ❌ | Earlier versions of the React Native tracker supported error tracking for mobile platforms. This feature was removed in version 4.0.0 as it didn't work with JavaScript. Track errors manually using the application_error schema. | ||
| Flutter | ❌ | Use the application_error schema for your own custom event. | ||
| Roku | ❌ | Use the application_error schema for your own custom event. | ||
| Google Tag Manager | ✅ | v3 | ❌ |
The Errors plugin for the JavaScript trackers provides configuration for automatic tracking of unhandled exceptions, as well as a method for manually tracking handled exceptions.
The mobile trackers will capture unhandled exceptions. These can crash the app, so it's likely that the event will be sent after restart. Note that in some situations, it may not be possible to capture all exception details before the app crashes.
All exception events use the same application_error schema, which has the following properties:
application_error
EventExample
{
"programmingLanguage": "JAVA",
"message": "java.lang.OutOfMemoryError error raised",
"exceptionName": "java.lang.OutOfMemoryError",
"isFatal": true,
"threadName": "main",
"threadId": 1,
"lineNumber": 10,
"className": "android.graphics.BitmapFactory",
"stackTrace": "java.lang.OutOfMemoryError"
}
Properties and schema
- Table
- JSON schema
| Property | Description |
|---|---|
programmingLanguagestring | Required. Must be one of: JAVA, SCALA, KOTLIN, GROOVY, RUBY, GOLANG, JAVASCRIPT, PHP, PYTHON, OBJECTIVEC, SWIFT, C, CPLUSPLUS, CSHARP, ACTIONSCRIPT, LUA, RUST, HASKELL, CLOJURE, ERLANG, ELIXIR, CRYSTAL, PONY, NIM |
messagestring | Required. |
threadNamestring | Optional. |
threadIdinteger | Optional. |
stackTracestring | Optional. |
causeStackTracestring | Optional. |
lineNumberinteger | Optional. |
classNamestring | Optional. |
exceptionNamestring | Optional. |
isFatalboolean | Optional. |
lineColumninteger | Optional. |
fileNamestring | Optional. |
{
"$schema": "http://iglucentral.com/schemas/com.snowplowanalytics.self-desc/schema/jsonschema/1-0-0#",
"description": "Schema for an application error",
"self": {
"vendor": "com.snowplowanalytics.snowplow",
"name": "application_error",
"format": "jsonschema",
"version": "1-0-2"
},
"type": "object",
"properties": {
"programmingLanguage": {
"type": "string",
"enum": [
"JAVA",
"SCALA",
"KOTLIN",
"GROOVY",
"RUBY",
"GOLANG",
"JAVASCRIPT",
"PHP",
"PYTHON",
"OBJECTIVEC",
"SWIFT",
"C",
"CPLUSPLUS",
"CSHARP",
"ACTIONSCRIPT",
"LUA",
"RUST",
"HASKELL",
"CLOJURE",
"ERLANG",
"ELIXIR",
"CRYSTAL",
"PONY",
"NIM"
]
},
"message": {
"type": "string",
"maxLength": 2048
},
"threadName": {
"type": [
"string",
"null"
],
"maxLength": 1024
},
"threadId": {
"type": [
"integer",
"null"
],
"minimum": 0,
"maximum": 2147483647
},
"stackTrace": {
"type": [
"string",
"null"
],
"maxLength": 8192
},
"causeStackTrace": {
"type": [
"string",
"null"
],
"maxLength": 8192
},
"lineNumber": {
"type": [
"integer",
"null"
],
"minimum": 0,
"maximum": 2147483647
},
"className": {
"type": [
"string",
"null"
],
"maxLength": 1024
},
"exceptionName": {
"type": [
"string",
"null"
],
"maxLength": 1024
},
"isFatal": {
"type": [
"boolean",
"null"
]
},
"lineColumn": {
"type": [
"integer",
"null"
],
"minimum": 0,
"maximum": 2147483647
},
"fileName": {
"type": [
"string",
"null"
],
"maxLength": 1024
}
},
"required": [
"programmingLanguage",
"message"
],
"additionalProperties": false
}
Warehouse query
- Snowflake
- BigQuery
- Databricks
- Redshift & Postgres
select
unstruct_event_com_snowplowanalytics_snowplow_application_error_1 application_error_1
from
atomic.events
where
events.collector_tstamp > getdate() - interval '1 hour'
and events.event = 'unstruct'
and events.event_name = 'application_error'
and events.event_vendor = 'com.snowplowanalytics.snowplow'
select
unstruct_event_com_snowplowanalytics_snowplow_application_error_1_0_2
from
PIPELINE_NAME.events events
where
events.collector_tstamp > timestamp_sub(current_timestamp(), interval 1 hour)
and events.event = 'unstruct'
and events.event_name = 'application_error'
and events.event_vendor = 'com.snowplowanalytics.snowplow'
select
unstruct_event_com_snowplowanalytics_snowplow_application_error_1
from
atomic.events events
where
events.collector_tstamp > timestampadd(HOUR, -1, current_timestamp())
and events.event = 'unstruct'
and events.event_name = 'application_error'
and events.event_vendor = 'com.snowplowanalytics.snowplow'
and unstruct_event_com_snowplowanalytics_snowplow_application_error_1 is not null
select
"application_error_1".*
from
atomic.events events
join atomic.com_snowplowanalytics_snowplow_application_error_1 "application_error_1"
on "application_error_1".root_id = events.event_id and "application_error_1".root_tstamp = events.collector_tstamp
where
events.collector_tstamp > getdate() - interval '1 hour'
and "application_error_1".root_tstamp > getdate() - interval '1 hour'
and events.event = 'unstruct'
and events.event_name = 'application_error'
and events.event_vendor = 'com.snowplowanalytics.snowplow'