Browse documentation

Instrument

Capture errors and releases

Send actionable errors, keep grouping useful, and resolve production stack frames.

Teml groups similar error events into Issues. Good error context makes those Issues easier to prioritize and connects them to the customers and releases they affected.

Capture unexpected failures

Use your SDK’s error method inside an existing error boundary. Continue to preserve the application’s normal failure behavior.

JavaScript / TypeScript

try {
  await chargeCard();
} catch (error) {
  teml.captureError(error as Error, {
    tags: { component: 'payments' },
  });
  throw error;
}

Python

try:
    charge_card()
except Exception as error:
    client.capture_error(error, tags={'component': 'payments'})
    raise

Go

if err := chargeCard(ctx); err != nil {
	client.CaptureError(ctx, err, teml.WithTag("component", "payments"))
	return err
}

Swift (iOS)

do {
    try chargeCard()
} catch {
    Teml.captureError(error, options: CaptureOptions(tags: ["component": "payments"]))
    throw error
}

Kotlin (Android)

try {
    chargeCard()
} catch (error: Exception) {
    Teml.captureError(error, CaptureOptions(tags = mapOf("component" to "payments")))
    throw error
}

React Native

try {
  await chargeCard();
} catch (error) {
  await Teml.captureError(error, { tags: { component: 'payments' } });
  throw error;
}

Flutter

try {
  await chargeCard();
} catch (error, stackTrace) {
  await Teml.captureError(
    error,
    stackTrace,
    options: const CaptureOptions(tags: {'component': 'payments'}),
  );
  rethrow;
}

Do not capture expected validation failures as errors. Use a diagnostic event when the outcome is useful investigation context but does not require engineering action.

Add useful context

Prefer low-cardinality tags such as component, operation, or payment provider. Customer identity should come from the active identity context, not from a duplicate error tag.

Never attach passwords, authorization headers, access tokens, or unfiltered request bodies.

Set release and distribution

Every production build should send a stable release identifier. Use dist when the same release has multiple artifacts.

JavaScript / TypeScript

const teml = await new TemlClient({
  apiKey: process.env.TEML_API_KEY,
  serviceName: 'web',
  release: process.env.GIT_SHA,
  dist: 'browser',
}).start();

Python

client = teml.TemlClient(
    api_key=os.environ['TEML_API_KEY'],
    service_name='payments',
    service_version=os.environ['RELEASE'],
)

Go

client, err := teml.New(
	teml.WithAPIKey(os.Getenv("TEML_API_KEY")),
	teml.WithServiceName("payments"),
	teml.WithServiceVersion(os.Getenv("RELEASE")),
	teml.WithErrorRelease(os.Getenv("RELEASE")),
)

Swift (iOS)

Teml.configure(TemlOptions(
    apiKey: apiKey,
    release: release,
    dist: buildNumber
))

Kotlin (Android)

Teml.init(
    applicationContext,
    TemlOptions(apiKey = apiKey, release = release, dist = buildNumber),
)

React Native

await Teml.configure({ apiKey, release, dist: buildNumber });

Flutter

await Teml.configure(TemlOptions(
  apiKey: apiKey,
  release: release,
  dist: buildNumber,
));

Python and Go currently use the service version as the release identifier; their public SDK options do not expose a separate dist field. Keep that version identical to the release registered by CI. Mobile and JavaScript integrations can additionally distinguish symbol artifacts with dist.

Where a platform uploads symbols, both release and distribution must match the artifact upload exactly.

Upload symbols in CI

The Teml CLI supports JavaScript source maps, Android ProGuard/R8 mappings, and iOS dSYMs.

teml symbols upload-proguard mapping.txt --release "$RELEASE" --dist "$DIST"
teml symbols upload-dsym App.dSYM/Contents/Resources/DWARF/App
teml symbols upload-sourcemap --file sourcemap-upload.json

For iOS, pass the Mach-O file inside the .dSYM bundle, not the bundle directory. Symbol uploads require errors:write; add releases:write only when the CI job also registers a release.

Upload one JavaScript source map per minified filename. sourcemap-upload.json has this shape; the content value is the raw .map JSON encoded as a JSON string:

{
  "release": "web@2.4.1",
  "dist": "browser",
  "filename": "assets/app.js",
  "content": "{\"version\":3,\"sources\":[\"src/app.ts\"],\"names\":[],\"mappings\":\"\"}"
}

Run uploads after building and before deleting artifacts. Keep symbols private. JavaScript map content must be smaller than 8 MiB; native upload limits are enforced separately.

Verify

Trigger one test error from a release build. In Issues, confirm the stack points to application source and that the affected customer and release are present.