Skip to content

Commit

Permalink
Merge pull request #1281 from microsoft/feature/track-exception
Browse files Browse the repository at this point in the history
Feature track exception
  • Loading branch information
guperrot committed Oct 24, 2019
2 parents 7f78663 + 1844d02 commit 554205e
Show file tree
Hide file tree
Showing 21 changed files with 519 additions and 442 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
@@ -1,6 +1,10 @@
# App Center SDK for Android Change Log

## Version 2.4.2 (Under development)
## Version 2.5.0 (Under development)

### App Center Crashes

* **[Feature]** Add the `Crash.trackException` method to send handled errors.

___

Expand Down
Expand Up @@ -5,17 +5,11 @@

package com.microsoft.appcenter.crashes;

import java.util.Map;

public final class CrashesPrivateHelper {

private CrashesPrivateHelper() {
}

public static void trackException(Throwable throwable, Map<String, String> properties) {
Crashes.trackException(throwable, properties);
}

public static void saveUncaughtException(Thread thread, Throwable exception) {
Crashes.getInstance().saveUncaughtException(thread, exception);
}
Expand Down
@@ -0,0 +1,103 @@
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/

package com.microsoft.appcenter.sasquatch;

import android.app.Activity;

import com.microsoft.appcenter.crashes.Crashes;
import com.microsoft.appcenter.crashes.model.TestCrashException;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Random;

public class CrashTestHelper {

private final List<Crash> mCrashes = Arrays.asList(
new Crash(R.string.title_test_crash, R.string.description_test_crash, new Runnable() {

@Override
public void run() {
Crashes.generateTestCrash();
throw new TestCrashException();
}
}),
new Crash(R.string.title_crash_divide_by_0, R.string.description_crash_divide_by_0, new Runnable() {

@Override
@SuppressWarnings("ResultOfMethodCallIgnored")
public void run() {
("" + (42 / Integer.valueOf("0"))).toCharArray();
}
}),
new Crash(R.string.title_stack_overflow_crash, R.string.description_stack_overflow_crash, new Runnable() {

@Override
@SuppressWarnings("InfiniteRecursion")
public void run() {
run();
}
}),
new Crash(R.string.title_nested_exception_crash, R.string.description_nested_exception_crash, new Runnable() {

@Override
public void run() {
throw new RuntimeException("HTTP call failed", new IOException("Broken pipe"));
}
}),
new Crash(R.string.title_deeply_nested_exception_crash, R.string.description_deeply_nested_exception_crash, new Runnable() {

@Override
public void run() {
Exception e = new Exception();
for (int i = 0; i < 1000; i++) {
e = new Exception(String.valueOf(i), e);
}
throw new RuntimeException(e);
}
}),
new Crash(R.string.title_memory_crash, R.string.description_memory_crash, new Runnable() {

@Override
public void run() {
new int[Integer.MAX_VALUE].clone();
}
}),
new Crash(R.string.title_variable_message, R.string.description_variable_message, new Runnable() {

@Override
public void run() {
mActivity.getResources().openRawResource(~new Random().nextInt(10));
}
})
);

private Activity mActivity;

public CrashTestHelper(Activity activity) {
mActivity = activity;
}

public List<Crash> getCrashes() {
return mCrashes;
}

public static class Crash {

public final int title;

public final int description;

public final Runnable crashTask;

public Crash(int title, int description, Runnable crashTask) {
this.title = title;
this.description = description;
this.crashTask = crashTask;
}
}
}
Expand Up @@ -6,13 +6,11 @@
package com.microsoft.appcenter.sasquatch.activities;

import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
Expand All @@ -22,14 +20,12 @@
import android.widget.ListView;
import android.widget.TextView;

import com.microsoft.appcenter.crashes.Crashes;
import com.microsoft.appcenter.crashes.model.TestCrashException;
import com.microsoft.appcenter.sasquatch.CrashTestHelper;
import com.microsoft.appcenter.sasquatch.R;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;

import static com.microsoft.appcenter.sasquatch.activities.CrashSubActivity.INTENT_EXTRA_CRASH_TYPE;
Expand All @@ -41,102 +37,53 @@ public class CrashActivity extends AppCompatActivity {

private boolean mCrashSuperDestroyNotCalled;

private final List<Crash> sCrashes = Arrays.asList(
new Crash(R.string.title_test_crash, R.string.description_test_crash, new Runnable() {
private final List<CrashTestHelper.Crash> mSpecificCrashes = Arrays.asList(
new CrashTestHelper.Crash(R.string.title_memory_crash2, R.string.description_memory_crash2, new Runnable() {

@Override
public void run() {
Crashes.generateTestCrash();
throw new TestCrashException();
startActivity(new Intent(CrashActivity.this, CrashSubActivity.class).putExtra(CrashSubActivity.INTENT_EXTRA_CRASH_TYPE, 1));
}
}),
new Crash(R.string.title_crash_divide_by_0, R.string.description_crash_divide_by_0, new Runnable() {
new CrashTestHelper.Crash(R.string.title_variable_message2, R.string.description_variable_message2, new Runnable() {

@Override
@SuppressWarnings("ResultOfMethodCallIgnored")
public void run() {
("" + (42 / Integer.valueOf("0"))).toCharArray();
startActivity(new Intent(CrashActivity.this, CrashSubActivity.class).putExtra(INTENT_EXTRA_CRASH_TYPE, 2));
}
}),
new Crash(R.string.title_test_ui_crash, R.string.description_test_ui_crash, new Runnable() {
new CrashTestHelper.Crash(R.string.title_test_ui_crash, R.string.description_test_ui_crash, new Runnable() {

@Override
public void run() {
ListView view = findViewById(R.id.list);
view.setAdapter(new ArrayAdapter<>(CrashActivity.this, android.R.layout.simple_list_item_2, sCrashes));
}
}),
new Crash(R.string.title_stack_overflow_crash, R.string.description_stack_overflow_crash, new Runnable() {

@Override
@SuppressWarnings("InfiniteRecursion")
public void run() {
run();
}
}),
new Crash(R.string.title_deeply_nested_exception_crash, R.string.description_deeply_nested_exception_crash, new Runnable() {

@Override
public void run() {
Exception e = new Exception();
for (int i = 0; i < 1000; i++) {
e = new Exception(String.valueOf(i), e);
}
throw new RuntimeException(e);
}
}),
new Crash(R.string.title_memory_crash, R.string.description_memory_crash, new Runnable() {

@Override
public void run() {
new int[Integer.MAX_VALUE].clone();
view.setAdapter(new ArrayAdapter<>(CrashActivity.this, android.R.layout.simple_list_item_2, mSpecificCrashes));
}
}),
new Crash(R.string.title_memory_crash2, R.string.description_memory_crash2, new Runnable() {

@Override
public void run() {
startActivity(new Intent(CrashActivity.this, CrashSubActivity.class).putExtra(INTENT_EXTRA_CRASH_TYPE, 1));
}
}),
new Crash(R.string.title_variable_message, R.string.description_variable_message, new Runnable() {

@Override
public void run() {
getResources().openRawResource(~new Random().nextInt(10));
}
}),
new Crash(R.string.title_variable_message2, R.string.description_variable_message2, new Runnable() {

@Override
public void run() {
startActivity(new Intent(CrashActivity.this, CrashSubActivity.class).putExtra(INTENT_EXTRA_CRASH_TYPE, 2));
}
}),
new Crash(R.string.title_super_not_called_exception, R.string.description_super_not_called_exception, new Runnable() {
new CrashTestHelper.Crash(R.string.title_super_not_called_exception, R.string.description_super_not_called_exception, new Runnable() {

@Override
public void run() {
mCrashSuperPauseNotCalled = true;
finish();
}
}),
new Crash(R.string.title_super_not_called_exception2, R.string.description_super_not_called_exception2, new Runnable() {
new CrashTestHelper.Crash(R.string.title_super_not_called_exception2, R.string.description_super_not_called_exception2, new Runnable() {

@Override
public void run() {
mCrashSuperDestroyNotCalled = true;
finish();
}
}),
new Crash(R.string.title_super_not_called_exception3, R.string.description_super_not_called_exception3, new Runnable() {
new CrashTestHelper.Crash(R.string.title_super_not_called_exception3, R.string.description_super_not_called_exception3, new Runnable() {

@Override
public void run() {
startActivity(new Intent(CrashActivity.this, CrashSubActivity.class).putExtra(INTENT_EXTRA_CRASH_TYPE, 0));
}
}),
new Crash(R.string.title_super_not_called_exception4, R.string.description_super_not_called_exception4, new Runnable() {
new CrashTestHelper.Crash(R.string.title_super_not_called_exception4, R.string.description_super_not_called_exception4, new Runnable() {

@Override
public void run() {
Expand All @@ -145,28 +92,28 @@ public void run() {
}),

/* NDK crashes */
new Crash(R.string.title_test_native_crash, R.string.description_test_native_crash, new Runnable() {
new CrashTestHelper.Crash(R.string.title_test_native_crash, R.string.description_test_native_crash, new Runnable() {

@Override
public void run() {
nativeDereferenceNullPointer();
}
}),
new Crash(R.string.title_native_stack_overflow_crash, R.string.description_native_stack_overflow_crash, new Runnable() {
new CrashTestHelper.Crash(R.string.title_native_stack_overflow_crash, R.string.description_native_stack_overflow_crash, new Runnable() {

@Override
public void run() {
nativeStackOverflowCrash();
}
}),
new Crash(R.string.title_native_abort_crash, R.string.description_native_abort_crash, new Runnable() {
new CrashTestHelper.Crash(R.string.title_native_abort_crash, R.string.description_native_abort_crash, new Runnable() {

@Override
public void run() {
nativeAbortCall();
}
}),
new Crash(R.string.title_low_memory_warning, R.string.description_low_memory_warning, new Runnable() {
new CrashTestHelper.Crash(R.string.title_low_memory_warning, R.string.description_low_memory_warning, new Runnable() {

@Override
public void run() {
Expand Down Expand Up @@ -198,7 +145,9 @@ protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_list);

ListView listView = findViewById(R.id.list);
listView.setAdapter(new ArrayAdapter<Crash>(this, android.R.layout.simple_list_item_2, android.R.id.text1, sCrashes) {
ArrayList<CrashTestHelper.Crash> crashes = new ArrayList<>(new CrashTestHelper(this).getCrashes());
crashes.addAll(mSpecificCrashes);
listView.setAdapter(new ArrayAdapter<CrashTestHelper.Crash>(this, android.R.layout.simple_list_item_2, android.R.id.text1, crashes) {

@SuppressWarnings("ConstantConditions")
@NonNull
Expand All @@ -214,7 +163,7 @@ public View getView(int position, @Nullable View convertView, @NonNull ViewGroup

@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
((Crash) parent.getItemAtPosition(position)).crashTask.run();
((CrashTestHelper.Crash) parent.getItemAtPosition(position)).crashTask.run();
}
});
}
Expand All @@ -232,20 +181,4 @@ protected void onDestroy() {
super.onDestroy();
}
}

@VisibleForTesting
static class Crash {

final int title;

final int description;

final Runnable crashTask;

Crash(int title, int description, Runnable crashTask) {
this.title = title;
this.description = description;
this.crashTask = crashTask;
}
}
}
Expand Up @@ -12,7 +12,7 @@

public class CrashSubActivity extends AppCompatActivity {

static final String INTENT_EXTRA_CRASH_TYPE = "INTENT_EXTRA_CRASH_TYPE";
public static final String INTENT_EXTRA_CRASH_TYPE = "INTENT_EXTRA_CRASH_TYPE";

@Override
@SuppressLint("MissingSuperCall")
Expand Down

0 comments on commit 554205e

Please sign in to comment.