Skip to content

Commit

Permalink
Merge pull request #30 from hrafnkellbaldurs/crashes-android-last-ses…
Browse files Browse the repository at this point in the history
…sion-crash-report

Crashes android last session crash report
  • Loading branch information
johnborges authored Sep 22, 2021
2 parents 4ce6f55 + 6e44dcc commit f4ff02d
Show file tree
Hide file tree
Showing 13 changed files with 257 additions and 25 deletions.
6 changes: 6 additions & 0 deletions appcenter-crashes/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Change Log

## 0.5.0

### Features

* **android**: Add `Crashes.lastSessionCrashReport()` API to get a report for the crash that happened in your last session in your app.

## 0.4.0

* adding Android support
Expand Down
3 changes: 2 additions & 1 deletion appcenter-crashes/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,14 +154,15 @@ Provides details about the crash that occurred in the last app session.
| Prop | Type | Description |
| -------------------------- | ----------------------------------------- | -------------------------------------------------------------------- |
| **`id`** | <code>string</code> | UUID for the crash report. |
| **`threadName`** | <code>string</code> | |
| **`threadName`** | <code>string</code> | Thread name that triggered the crash |
| **`appErrorTime`** | <code>string \| number</code> | Date and time the error occurred. |
| **`appStartTime`** | <code>string \| number</code> | Date and time the app started. |
| **`exceptionName`** | <code>string</code> | Exception name that triggered the crash. |
| **`exceptionReason`** | <code>string</code> | Exception reason. |
| **`device`** | <code><a href="#device">Device</a></code> | <a href="#device">Device</a> information of the app when it crashed. |
| **`signal`** | <code>string</code> | Signal that caused the crash. |
| **`appProcessIdentifier`** | <code>number</code> | Identifier of the app process that crashed. |
| **`stackTrace`** | <code>string</code> | The stack trace of the crash |


#### Device
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.getcapacitor.plugin.appcenter.crashes;

import com.getcapacitor.JSObject;
import com.microsoft.appcenter.AppCenter;
import com.microsoft.appcenter.crashes.Crashes;

Expand Down Expand Up @@ -31,8 +32,7 @@ public boolean hasCrashedInLastSession() {
return Crashes.hasCrashedInLastSession().get();
}

// public void lastSessionCrashReport() {
// return Crashes.lastSessionCrashReport().get()
// }

public JSObject lastSessionCrashReport() {
return CrashesUtil.convertReportToJs(Crashes.getLastSessionCrashReport().get());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,12 @@
import com.getcapacitor.PluginMethod;
import com.getcapacitor.annotation.CapacitorPlugin;

import com.microsoft.appcenter.AppCenter;
import com.microsoft.appcenter.crashes.Crashes;
import com.microsoft.appcenter.reactnative.shared.AppCenterReactNativeShared;

@CapacitorPlugin(name = "Crashes")
public class CrashesPlugin extends Plugin {

private CrashesBase implementation = new CrashesBase();
private final CrashesBase implementation = new CrashesBase();

@Override
public void load() {
Expand All @@ -23,7 +21,11 @@ public void load() {

@PluginMethod(returnType = PluginMethod.RETURN_NONE)
public void setEnable(PluginCall call) {
implementation.enable(call.getBoolean("enable", false));
Boolean enable = call.getBoolean("enable", false);
if (enable == null) {
enable = false;
}
implementation.enable(enable);
call.resolve();
}

Expand Down Expand Up @@ -56,7 +58,14 @@ public void hasCrashedInLastSession(PluginCall call) {

@PluginMethod
public void lastSessionCrashReport(PluginCall call) {
call.unimplemented("Not yet implemented on Android.");
JSObject lastSessionCrashReport = implementation.lastSessionCrashReport();
if (lastSessionCrashReport == null) {
call.reject("No crash report available");
return;
}
JSObject ret = new JSObject();
ret.put("value", lastSessionCrashReport);
call.resolve(ret);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package com.getcapacitor.plugin.appcenter.crashes;

import android.util.Log;

import com.getcapacitor.JSObject;
import com.microsoft.appcenter.crashes.model.ErrorReport;
import com.microsoft.appcenter.ingestion.models.Device;

import java.util.ArrayList;
import java.util.List;

/**
* Utility class containing helpers for converting App Center objects.
*/
public class CrashesUtil {
private static final String LOG_TAG = "AppCenterCrashes";

public static void logError(String message) {
Log.e(LOG_TAG, message);
}

static void logInfo(String message) {
Log.i(LOG_TAG, message);
}

static void logDebug(String message) {
Log.d(LOG_TAG, message);
}

/**
* Serializes App Center Device properties to Dictionary
* @param device App Center Device
* @return Device Dictionary
*/
public static JSObject serializeDeviceToJs(Device device) {
if (device == null) {
return null;
}
JSObject dict = new JSObject();

dict.put("sdkName", device.getSdkName());
dict.put("sdkVersion", device.getSdkVersion());
dict.put("model", device.getModel());
dict.put("oemName", device.getOemName());
dict.put("osName", device.getOsName());
dict.put("osVersion", device.getOsVersion());
if (device.getOsBuild() != null) {
dict.put("osBuild", device.getOsBuild());
}
if (device.getOsApiLevel() != null) {
dict.put("osApiLevel", device.getOsApiLevel());
}
dict.put("locale", device.getLocale());
dict.put("timeZoneOffset", device.getTimeZoneOffset());
dict.put("screenSize", device.getScreenSize());
dict.put("appVersion", device.getAppVersion());
if (device.getCarrierName() != null) {
dict.put("carrierName", device.getCarrierName());
}
if (device.getCarrierCountry() != null) {
dict.put("carrierCountry", device.getCarrierCountry());
}
dict.put("appBuild", device.getAppBuild());
if (device.getAppNamespace() != null) {
dict.put("appNamespace", device.getAppNamespace());
}

return dict;
}

/**
* Converts App Center ErrorReport to Dictionary
* @param report App Center ErrorReport
* @return JS optional Dictionary
*/
public static JSObject convertReportToJs(ErrorReport report) {
if (report == null) {
return null;
}

JSObject dict = new JSObject();

dict.put("id", report.getId());

if (report.getThreadName() != null) {
String threadName = report.getThreadName();
dict.put("threadName", threadName);
}

if (report.getStackTrace() != null) {
String stackTrace = report.getStackTrace();
dict.put("stackTrace", stackTrace);
}

if (report.getAppStartTime() != null) {
String appStartTime = Long.toString(report.getAppStartTime().getTime());
dict.put("appStartTime", appStartTime);
}

if (report.getAppErrorTime() != null) {
String appErrorTime = Long.toString(report.getAppErrorTime().getTime());
dict.put("appErrorTime", appErrorTime);
}

dict.put("device", serializeDeviceToJs(report.getDevice()));

return dict;
}

/**
* Converts list of App Center ErrorReports to a list of maps
* @param reports App Center ErrorReport list
* @return List of maps
*/
public static List<JSObject> convertReportsToJs(List<ErrorReport> reports) {
List<JSObject> jsReadyReports = new ArrayList<>();

if (reports == null) {
return jsReadyReports;
}

for(int i = 0; i < reports.size(); i++) {
ErrorReport report = reports.get(i);
JSObject convertedReport = convertReportToJs(report);
if (convertedReport != null) {
jsReadyReports.add(convertedReport);
}
}

return jsReadyReports;
}
}
2 changes: 1 addition & 1 deletion appcenter-crashes/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@capacitor-community/appcenter-crashes",
"version": "0.4.0",
"version": "0.5.0",
"description": "Capacitor plugin for Microsoft's App Center Crashes",
"main": "dist/plugin.cjs.js",
"module": "dist/esm/index.js",
Expand Down
11 changes: 9 additions & 2 deletions appcenter-crashes/src/definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ export interface ErrorReport {
* UUID for the crash report.
*/
id: string;
/**
* Thread name that triggered the crash
*/
threadName?: string;
/**
* Date and time the error occurred.
Expand All @@ -100,11 +103,15 @@ export interface ErrorReport {
/**
* Signal that caused the crash.
*/
signal: string;
signal?: string;
/**
* Identifier of the app process that crashed.
*/
appProcessIdentifier: number;
appProcessIdentifier?: number;
/**
* The stack trace of the crash
*/
stackTrace?: string;
}

export interface CrashesListener {
Expand Down
2 changes: 1 addition & 1 deletion appcenter-crashes/src/web.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { WebPlugin } from '@capacitor/core';

import { CrashesPlugin, ErrorReport } from './definitions';
import type { CrashesPlugin, ErrorReport } from './definitions';

export class CrashesWeb
extends WebPlugin
Expand Down
2 changes: 1 addition & 1 deletion example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"dependencies": {
"@capacitor-community/appcenter": "^0.7.0",
"@capacitor-community/appcenter-analytics": "^0.3.0",
"@capacitor-community/appcenter-crashes": "^0.4.0",
"@capacitor-community/appcenter-crashes": "^0.5.0",
"@capacitor/android": "^3.0.0",
"@capacitor/app": "^1.0.0",
"@capacitor/cli": "^3.0.0",
Expand Down
16 changes: 16 additions & 0 deletions example/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* It contains typing information for all components that exist in this project.
*/
import { HTMLStencilElement, JSXBase } from "@stencil/core/internal";
import { ErrorReportItem } from "./components/app-crashes/error-report-items-modal";
export namespace Components {
interface AppAnalytics {
}
Expand All @@ -14,6 +15,9 @@ export namespace Components {
}
interface AppRoot {
}
interface ErrorReportItemsModal {
"items": ErrorReportItem[];
}
}
declare global {
interface HTMLAppAnalyticsElement extends Components.AppAnalytics, HTMLStencilElement {
Expand All @@ -40,11 +44,18 @@ declare global {
prototype: HTMLAppRootElement;
new (): HTMLAppRootElement;
};
interface HTMLErrorReportItemsModalElement extends Components.ErrorReportItemsModal, HTMLStencilElement {
}
var HTMLErrorReportItemsModalElement: {
prototype: HTMLErrorReportItemsModalElement;
new (): HTMLErrorReportItemsModalElement;
};
interface HTMLElementTagNameMap {
"app-analytics": HTMLAppAnalyticsElement;
"app-crashes": HTMLAppCrashesElement;
"app-home": HTMLAppHomeElement;
"app-root": HTMLAppRootElement;
"error-report-items-modal": HTMLErrorReportItemsModalElement;
}
}
declare namespace LocalJSX {
Expand All @@ -56,11 +67,15 @@ declare namespace LocalJSX {
}
interface AppRoot {
}
interface ErrorReportItemsModal {
"items"?: ErrorReportItem[];
}
interface IntrinsicElements {
"app-analytics": AppAnalytics;
"app-crashes": AppCrashes;
"app-home": AppHome;
"app-root": AppRoot;
"error-report-items-modal": ErrorReportItemsModal;
}
}
export { LocalJSX as JSX };
Expand All @@ -71,6 +86,7 @@ declare module "@stencil/core" {
"app-crashes": LocalJSX.AppCrashes & JSXBase.HTMLAttributes<HTMLAppCrashesElement>;
"app-home": LocalJSX.AppHome & JSXBase.HTMLAttributes<HTMLAppHomeElement>;
"app-root": LocalJSX.AppRoot & JSXBase.HTMLAttributes<HTMLAppRootElement>;
"error-report-items-modal": LocalJSX.ErrorReportItemsModal & JSXBase.HTMLAttributes<HTMLErrorReportItemsModalElement>;
}
}
}
Loading

0 comments on commit f4ff02d

Please sign in to comment.