Skip to content

Commit e7fe695

Browse files
authored
Merge pull request #655 from F43nd1r/issue_654
Fix handleSilentException bugs
2 parents 3927f0c + 813a764 commit e7fe695

File tree

4 files changed

+50
-14
lines changed

4 files changed

+50
-14
lines changed

acra-core/src/main/java/org/acra/builder/ReportExecutor.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import android.support.annotation.NonNull;
2323
import android.support.annotation.Nullable;
2424
import android.widget.Toast;
25+
2526
import org.acra.ACRA;
2627
import org.acra.ACRAConstants;
2728
import org.acra.config.CoreConfiguration;
@@ -249,9 +250,7 @@ private void startSendingReports(boolean onlySendSilentReports) {
249250
private File getReportFileName(@NonNull CrashReportData crashData) {
250251
final String timestamp = crashData.getString(USER_CRASH_DATE);
251252
final String isSilent = crashData.getString(IS_SILENT);
252-
final String fileName = (timestamp != null ? timestamp : new Date().getTime()) // Need to check for null because old version of ACRA did not always capture USER_CRASH_DATE
253-
+ (isSilent != null ? ACRAConstants.SILENT_SUFFIX : "")
254-
+ ACRAConstants.REPORTFILE_EXTENSION;
253+
final String fileName = timestamp + (isSilent != null ? ACRAConstants.SILENT_SUFFIX : "") + ACRAConstants.REPORTFILE_EXTENSION;
255254
final ReportLocator reportLocator = new ReportLocator(context);
256255
return new File(reportLocator.getUnapprovedFolder(), fileName);
257256
}

acra-core/src/main/java/org/acra/file/CrashReportFileNameParser.java

+28-4
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,23 @@
2020
import org.acra.ACRAConstants;
2121
import org.acra.ErrorReporter;
2222

23+
import java.text.ParseException;
24+
import java.text.SimpleDateFormat;
25+
import java.util.Calendar;
26+
import java.util.Locale;
27+
2328
/**
2429
* Responsible for determining the state of a Crash Report based on its file name.
2530
*
26-
* @author William Ferguson
31+
* @author William Ferguson & F43nd1r
2732
* @since 4.3.0
2833
*/
2934
public final class CrashReportFileNameParser {
3035

3136
/**
3237
* Guess that a report is silent from its file name.
3338
*
34-
* @param reportFileName Name of the report to check whether it should be sent silently.
39+
* @param reportFileName Name of the report to check whether it should be sent silently.
3540
* @return True if the report has been declared explicitly silent using {@link ErrorReporter#handleSilentException(Throwable)}.
3641
*/
3742
public boolean isSilent(@NonNull String reportFileName) {
@@ -41,17 +46,36 @@ public boolean isSilent(@NonNull String reportFileName) {
4146
/**
4247
* Returns true if the report is considered as approved.
4348
* <p>
44-
This includes:
49+
* This includes:
4550
* </p>
4651
* <ul>
4752
* <li>Reports which were pending when the user agreed to send a report in the NOTIFICATION mode Dialog.</li>
4853
* <li>Explicit silent reports</li>
4954
* </ul>
5055
*
51-
* @param reportFileName Name of report to check whether it is approved to be sent.
56+
* @param reportFileName Name of report to check whether it is approved to be sent.
5257
* @return True if a report can be sent.
58+
* @deprecated use {@link ReportLocator#getApprovedReports()} and {@link ReportLocator#getUnapprovedReports()} instead
5359
*/
60+
@Deprecated
5461
public boolean isApproved(@NonNull String reportFileName) {
5562
return isSilent(reportFileName) || reportFileName.contains(ACRAConstants.APPROVED_SUFFIX);
5663
}
64+
65+
/**
66+
* Gets the timestamp of a report from its name
67+
*
68+
* @param reportFileName Name of the report to get the timestamp from.
69+
* @return timestamp of the report
70+
*/
71+
@NonNull
72+
public Calendar getTimestamp(@NonNull String reportFileName) {
73+
final String timestamp = reportFileName.replace(ACRAConstants.REPORTFILE_EXTENSION, "").replace(ACRAConstants.SILENT_SUFFIX, "");
74+
final Calendar calendar = Calendar.getInstance();
75+
try {
76+
calendar.setTime(new SimpleDateFormat(ACRAConstants.DATE_TIME_FORMAT_STRING, Locale.ENGLISH).parse(timestamp));
77+
} catch (ParseException ignored) {
78+
}
79+
return calendar;
80+
}
5781
}

acra-core/src/main/java/org/acra/sender/SenderService.java

+6-3
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,13 @@ protected void onHandleWork(@NonNull Intent intent) {
7979
// Iterate over approved reports and send via all Senders.
8080
int reportsSentCount = 0; // Use to rate limit sending
8181
final CrashReportFileNameParser fileNameParser = new CrashReportFileNameParser();
82+
boolean anyNonSilent = false;
8283
for (final File report : reports) {
83-
if (onlySendSilentReports && !fileNameParser.isSilent(report.getName())) {
84+
final boolean isNonSilent = !fileNameParser.isSilent(report.getName());
85+
if (onlySendSilentReports && isNonSilent) {
8486
continue;
8587
}
88+
anyNonSilent |= isNonSilent;
8689

8790
if (reportsSentCount >= ACRAConstants.MAX_SEND_REPORTS) {
8891
break; // send only a few reports to avoid overloading the network
@@ -92,8 +95,8 @@ protected void onHandleWork(@NonNull Intent intent) {
9295
reportsSentCount++;
9396
}
9497
}
95-
final String toast = reportsSentCount > 0 ? config.reportSendSuccessToast() : config.reportSendFailureToast();
96-
if (toast != null) {
98+
final String toast;
99+
if (anyNonSilent && (toast = reportsSentCount > 0 ? config.reportSendSuccessToast() : config.reportSendFailureToast()) != null) {
97100
new Handler(Looper.getMainLooper()).post(() -> ToastSender.sendToast(this, toast, Toast.LENGTH_LONG));
98101
}
99102
} catch (Exception e) {

acra-core/src/main/java/org/acra/util/ApplicationStartupProcessor.java

+14-4
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,20 @@
2323
import android.support.annotation.NonNull;
2424

2525
import org.acra.ACRA;
26+
import org.acra.ACRAConstants;
2627
import org.acra.config.CoreConfiguration;
2728
import org.acra.file.BulkReportDeleter;
29+
import org.acra.file.CrashReportFileNameParser;
2830
import org.acra.file.ReportLocator;
2931
import org.acra.interaction.ReportInteractionExecutor;
3032
import org.acra.prefs.SharedPreferencesFactory;
3133
import org.acra.sender.SenderServiceStarter;
3234

3335
import java.io.File;
36+
import java.text.ParseException;
37+
import java.text.SimpleDateFormat;
38+
import java.util.Calendar;
39+
import java.util.Locale;
3440

3541
/**
3642
* Looks for any existing reports and starts sending them.
@@ -50,6 +56,7 @@ public ApplicationStartupProcessor(@NonNull Context context, @NonNull CoreConfig
5056
}
5157

5258
public void checkReports(boolean enableAcra) {
59+
final Calendar now = Calendar.getInstance();
5360
//application is not ready in onAttachBaseContext, so delay this. also run it on a background thread because we're doing disk I/O
5461
new Handler(context.getMainLooper()).post(() -> new Thread(() -> {
5562
if (config.deleteOldUnsentReportsOnApplicationStart()) {
@@ -60,19 +67,22 @@ public void checkReports(boolean enableAcra) {
6067
}
6168
if (enableAcra) {
6269
sendApprovedReports();
63-
approveOneReport();
70+
approveOneReport(now);
6471
}
6572
}).start());
6673
}
6774

68-
private void approveOneReport() {
75+
private void approveOneReport(Calendar ignoreReportsAfter) {
6976
final File[] reports = reportLocator.getUnapprovedReports();
7077

7178
if (reports.length == 0) {
7279
return; // There are no unapproved reports, so bail now.
7380
}
74-
//only approve one report at a time to prevent overwhelming users
75-
new ReportInteractionExecutor(context, config).performInteractions(reports[0]);
81+
//if a report was created after the application launch, it might be currently handled, so ignore it for now.
82+
if (new CrashReportFileNameParser().getTimestamp(reports[0].getName()).before(ignoreReportsAfter)) {
83+
//only approve one report at a time to prevent overwhelming users
84+
new ReportInteractionExecutor(context, config).performInteractions(reports[0]);
85+
}
7686
}
7787

7888
/**

0 commit comments

Comments
 (0)