Procházet zdrojové kódy

Switch to new Error Managers.

This is a little bit icky, but I can't see a nicer way to do it.
pull/450/head
Greg Holmes před 9 roky
rodič
revize
10ac78a271

+ 10
- 0
src/com/dmdirc/ClientModule.java Zobrazit soubor

@@ -49,6 +49,10 @@ import com.dmdirc.ui.themes.ThemeManager;
49 49
 import com.dmdirc.updater.UpdaterModule;
50 50
 import com.dmdirc.util.io.Downloader;
51 51
 
52
+import java.util.concurrent.ExecutorService;
53
+import java.util.concurrent.Executors;
54
+
55
+import javax.inject.Named;
52 56
 import javax.inject.Provider;
53 57
 import javax.inject.Qualifier;
54 58
 import javax.inject.Singleton;
@@ -101,6 +105,12 @@ public class ClientModule {
101 105
         return serverManager;
102 106
     }
103 107
 
108
+    @Provides
109
+    @Named("singlethread")
110
+    public ExecutorService getExecutorService() {
111
+        return Executors.newSingleThreadExecutor();
112
+    }
113
+
104 114
     @Provides
105 115
     @Singleton
106 116
     public DMDircMBassador getMBassador() {

+ 1
- 1
src/com/dmdirc/config/ConfigModule.java Zobrazit soubor

@@ -69,7 +69,6 @@ public class ConfigModule {
69 69
             final ErrorManager errorManager) {
70 70
         final IdentityManager identityManager = new IdentityManager(baseDirectory,
71 71
                 identitiesDirectory, eventBus, clientInfo);
72
-        errorManager.initialise(identityManager.getGlobalConfiguration(), errorsDirectory, eventBus);
73 72
         identityManager.loadVersionIdentity();
74 73
 
75 74
         try {
@@ -77,6 +76,7 @@ public class ConfigModule {
77 76
         } catch (InvalidIdentityFileException ex) {
78 77
             handleInvalidConfigFile(identityManager, baseDirectory);
79 78
         }
79
+        errorManager.initialise(identityManager.getGlobalConfiguration());
80 80
 
81 81
         if (commandLineParser.getDisableReporting()) {
82 82
             identityManager.getUserSettings().setOption("temp", "noerrorreporting", true);

+ 13
- 13
src/com/dmdirc/logger/DiskLoggingErrorManager.java Zobrazit soubor

@@ -23,6 +23,8 @@
23 23
 package com.dmdirc.logger;
24 24
 
25 25
 import com.dmdirc.DMDircMBassador;
26
+import com.dmdirc.commandline.CommandLineOptionsModule.Directory;
27
+import com.dmdirc.commandline.CommandLineOptionsModule.DirectoryType;
26 28
 import com.dmdirc.config.ConfigBinder;
27 29
 import com.dmdirc.config.ConfigBinding;
28 30
 import com.dmdirc.events.ErrorEvent;
@@ -39,11 +41,15 @@ import java.util.Arrays;
39 41
 import java.util.Date;
40 42
 import java.util.List;
41 43
 
44
+import javax.inject.Inject;
45
+import javax.inject.Singleton;
46
+
42 47
 import net.engio.mbassy.listener.Handler;
43 48
 
44 49
 /**
45 50
  * Listens for {@link ErrorEvent}s and writes them to disk.
46 51
  */
52
+@Singleton
47 53
 public class DiskLoggingErrorManager {
48 54
 
49 55
     /** The event bus to listen for errors on. */
@@ -51,31 +57,25 @@ public class DiskLoggingErrorManager {
51 57
     /** The directory to log errors to. */
52 58
     private final Path errorsDirectory;
53 59
     /** The config binder to use for settings. */
54
-    private final ConfigBinder configBinder;
60
+    private ConfigBinder configBinder;
55 61
     /** Error creating directory, don't write to disk. */
56 62
     private boolean directoryError;
57 63
     /** Are we logging errors to disk? */
58 64
     private boolean logging;
59 65
 
60
-    /**
61
-     * Creates a new instance of this error manager.
62
-     *
63
-     * @param errorsDirectory The directory to write errors to.  The error manager will try to
64
-     *                        create this if it is not present
65
-     * @param eventBus        The event bus to listen to errors on
66
-     * @param config          The config to read values from
67
-     */
68
-    public DiskLoggingErrorManager(final Path errorsDirectory, final DMDircMBassador eventBus,
69
-            final AggregateConfigProvider config) {
66
+    @Inject
67
+    public DiskLoggingErrorManager(
68
+            @Directory(DirectoryType.ERRORS)final Path errorsDirectory,
69
+            final DMDircMBassador eventBus) {
70 70
         this.errorsDirectory = errorsDirectory;
71 71
         this.eventBus = eventBus;
72
-        configBinder = config.getBinder();
73 72
     }
74 73
 
75 74
     /**
76 75
      * Initialises the error manager.  Must be called before logging will start.
77 76
      */
78
-    public void initialise() {
77
+    public void initialise(final AggregateConfigProvider config) {
78
+        configBinder = config.getBinder();
79 79
         configBinder.bind(this, DiskLoggingErrorManager.class);
80 80
         eventBus.subscribe(this);
81 81
         if (!Files.exists(errorsDirectory)) {

+ 27
- 400
src/com/dmdirc/logger/ErrorManager.java Zobrazit soubor

@@ -22,432 +22,59 @@
22 22
 
23 23
 package com.dmdirc.logger;
24 24
 
25
-import com.dmdirc.DMDircMBassador;
26
-import com.dmdirc.config.ConfigBinding;
27
-import com.dmdirc.events.AppErrorEvent;
28
-import com.dmdirc.events.FatalProgramErrorEvent;
29
-import com.dmdirc.events.NonFatalProgramErrorEvent;
30
-import com.dmdirc.events.ProgramErrorDeletedEvent;
31
-import com.dmdirc.events.UserErrorEvent;
32 25
 import com.dmdirc.interfaces.config.AggregateConfigProvider;
33
-import com.dmdirc.ui.FatalErrorDialog;
34
-import com.dmdirc.util.EventUtils;
35 26
 
36
-import com.google.common.collect.Lists;
37
-import com.google.common.collect.Sets;
38
-import com.google.common.util.concurrent.ThreadFactoryBuilder;
39
-
40
-import java.awt.GraphicsEnvironment;
41
-import java.io.IOException;
42
-import java.nio.charset.Charset;
43
-import java.nio.file.Files;
44
-import java.nio.file.Path;
45
-import java.util.Arrays;
46
-import java.util.Collections;
47
-import java.util.Date;
48
-import java.util.List;
49 27
 import java.util.Set;
50
-import java.util.concurrent.CopyOnWriteArraySet;
51
-import java.util.concurrent.CountDownLatch;
52
-import java.util.concurrent.ExecutorService;
53
-import java.util.concurrent.Executors;
54 28
 
55 29
 import javax.inject.Inject;
30
+import javax.inject.Provider;
56 31
 import javax.inject.Singleton;
57 32
 
58
-import net.engio.mbassy.listener.Handler;
59
-import net.kencochrane.raven.DefaultRavenFactory;
60
-import net.kencochrane.raven.RavenFactory;
61
-
62 33
 /**
63 34
  * Error manager.
64 35
  */
65 36
 @Singleton
66 37
 public class ErrorManager {
67 38
 
68
-    /** A list of exceptions which we don't consider bugs and thus don't report. */
69
-    private static final Class<?>[] BANNED_EXCEPTIONS = new Class<?>[]{
70
-        NoSuchMethodError.class, NoClassDefFoundError.class,
71
-        UnsatisfiedLinkError.class, AbstractMethodError.class,
72
-        IllegalAccessError.class, OutOfMemoryError.class,
73
-        NoSuchFieldError.class,};
74
-    /** Error list. */
75
-    private final Set<ProgramError> errors;
76
-    /** Countdown latch to wait for FED with. */
77
-    private final CountDownLatch countDownLatch;
78
-    /** Sentry error reporter factory. */
79
-    private final SentryErrorReporter sentryErrorReporter;
80
-    /** Factory to create program errors. */
81
-    private final ProgramErrorFactory programErrorFactory;
82
-    /** Event bus to subscribe and publish errors on. */
83
-    private DMDircMBassador eventBus;
84
-    /** Whether or not to send error reports. */
85
-    private boolean sendReports;
86
-    /** Whether or not to log error reports. */
87
-    private boolean logReports;
88
-    /** Whether to submit error reports. */
89
-    private boolean submitReports;
90
-    /** Temp no error reporting. */
91
-    private boolean tempNoErrors;
92
-    /** Error creating directory, don't write to disk. */
93
-    private boolean directoryError;
94
-    /** Thread used for sending errors. */
95
-    private ExecutorService reportThread;
96
-    /** Directory to store errors in. */
97
-    private Path errorsDirectory;
39
+    private final Provider<SentryLoggingErrorManager> sentryLoggingErrorManagerProvider;
40
+    private final Provider<ProgramErrorManager> programErrorManagerProvider;
41
+    private final Provider<DiskLoggingErrorManager> diskLoggingErrorManagerProvider;
42
+    private SentryLoggingErrorManager sentryLoggingErrorManager;
43
+    private ProgramErrorManager programErrorManager;
44
+    private DiskLoggingErrorManager diskLoggingErrorManager;
98 45
 
99
-    /** Creates a new instance of ErrorListDialog. */
100 46
     @Inject
101
-    public ErrorManager(final SentryErrorReporter sentryErrorReporter,
102
-            final ProgramErrorFactory programErrorFactory) {
103
-        errors = new CopyOnWriteArraySet<>();
104
-        countDownLatch = new CountDownLatch(2);
105
-        this.sentryErrorReporter = sentryErrorReporter;
106
-        this.programErrorFactory = programErrorFactory;
107
-    }
108
-
109
-    /**
110
-     * Initialises the error manager.
111
-     *
112
-     * @param globalConfig The configuration to read settings from.
113
-     * @param directory    The directory to store errors in, if enabled.
114
-     * @param eventBus     The event bus to listen for error events on.
115
-     */
116
-    public void initialise(final AggregateConfigProvider globalConfig, final Path directory,
117
-            final DMDircMBassador eventBus) {
118
-        this.eventBus = eventBus;
119
-        eventBus.subscribe(this);
120
-        RavenFactory.registerFactory(new DefaultRavenFactory());
121
-        reportThread = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder()
122
-                .setNameFormat("error-thread-%d").build());
123
-
124
-        globalConfig.getBinder().bind(this, ErrorManager.class);
125
-
126
-        errorsDirectory = directory;
127
-        if (!Files.exists(directory)) {
128
-            try {
129
-                Files.createDirectories(errorsDirectory);
130
-            } catch (IOException ex) {
131
-                directoryError = true;
132
-            }
133
-        }
134
-
135
-        // Loop through any existing errors and send/save them per the config.
136
-        for (ProgramError error : errors) {
137
-            if (sendReports && error.getReportStatus() == ErrorReportStatus.WAITING) {
138
-                sendError(error);
139
-            }
140
-
141
-            if (logReports) {
142
-                saveError(error);
143
-            }
144
-        }
47
+    public ErrorManager(
48
+            final Provider<SentryLoggingErrorManager> sentryLoggingErrorManagerProvider,
49
+            final Provider<ProgramErrorManager> programErrorManagerProvider,
50
+            final Provider<DiskLoggingErrorManager> diskLoggingErrorManagerProvider) {
51
+        this.sentryLoggingErrorManagerProvider = sentryLoggingErrorManagerProvider;
52
+        this.programErrorManagerProvider = programErrorManagerProvider;
53
+        this.diskLoggingErrorManagerProvider = diskLoggingErrorManagerProvider;
145 54
     }
146 55
 
147
-    @Handler(priority = EventUtils.PRIORITY_LOWEST)
148
-    public void handleAppErrorEvent(final AppErrorEvent appError) {
149
-        final ProgramError error = addError(appError.getLevel(), appError.getMessage(), appError
150
-                        .getThrowable(),
151
-                appError.getDetails(), true, isValidError(appError.getThrowable()));
152
-        if (appError.getLevel() == ErrorLevel.FATAL) {
153
-            eventBus.publish(new FatalProgramErrorEvent(error));
154
-        } else {
155
-            eventBus.publish(new NonFatalProgramErrorEvent(error));
156
-        }
56
+    public void initialise(final AggregateConfigProvider config) {
57
+        sentryLoggingErrorManager = sentryLoggingErrorManagerProvider.get();
58
+        diskLoggingErrorManager = diskLoggingErrorManagerProvider.get();
59
+        programErrorManager = programErrorManagerProvider.get();
60
+        sentryLoggingErrorManager.initialise(config);
61
+        diskLoggingErrorManager.initialise(config);
62
+        programErrorManager.initialise();
157 63
     }
158 64
 
159
-    @Handler(priority = EventUtils.PRIORITY_LOWEST)
160
-    public void handleUserErrorEvent(final UserErrorEvent userError) {
161
-        final ProgramError error = addError(userError.getLevel(), userError.getMessage(),
162
-                userError.getThrowable(), userError.getDetails(), false,
163
-                isValidError(userError.getThrowable()));
164
-        if (userError.getLevel() == ErrorLevel.FATAL) {
165
-            eventBus.publish(new FatalProgramErrorEvent(error));
166
-        } else {
167
-            eventBus.publish(new NonFatalProgramErrorEvent(error));
168
-        }
169
-    }
170
-
171
-    /**
172
-     * Adds a new error to the manager with the specified details.
173
-     *
174
-     * @param level     The severity of the error
175
-     * @param message   The error message
176
-     * @param throwable The exception that caused the error, if any.
177
-     * @param details   The details of the exception, if any.
178
-     * @param appError  Whether or not this is an application error
179
-     * @param canReport Whether or not this error can be reported
180
-     *
181
-     * @since 0.6.3m1
182
-     */
183
-    protected ProgramError addError(final ErrorLevel level, final String message,
184
-            final Throwable throwable, final String details, final boolean appError,
185
-            final boolean canReport) {
186
-        final ProgramError error = programErrorFactory.create(level, message, throwable,
187
-                getTrace(message, throwable), details, new Date(), appError);
188
-        return addError(error, appError, canReport);
189
-    }
190
-
191
-    protected ProgramError addError(
192
-            final ProgramError error,
193
-            final boolean appError,
194
-            final boolean canReport) {
195
-        addError(error);
196
-        if (!canReport || appError && !isValidSource(error) || !appError) {
197
-            error.setReportStatus(ErrorReportStatus.NOT_APPLICABLE);
198
-        } else if (sendReports) {
199
-            sendError(error);
200
-        }
201
-
202
-        if (logReports) {
203
-            saveError(error);
204
-        }
205
-        return error;
206
-    }
207
-
208
-
209
-
210
-    /**
211
-     * Determines whether or not the stack trace associated with this error is from a valid source.
212
-     * A valid source is one that is within a DMDirc package (com.dmdirc), and is not the DMDirc
213
-     * event queue.
214
-     *
215
-     * @return True if the source is valid, false otherwise
216
-     */
217
-    public boolean isValidSource(final ProgramError error) {
218
-        final String line = getSourceLine(error);
219
-
220
-        return line.startsWith("com.dmdirc")
221
-                && !line.startsWith("com.dmdirc.addons.ui_swing.DMDircEventQueue");
222
-    }
223
-
224
-    /**
225
-     * Returns the "source line" of this error, which is defined as the first line starting with a
226
-     * DMDirc package name (com.dmdirc). If no such line is found, returns the first line of the
227
-     * message.
228
-     *
229
-     * @return This error's source line
230
-     */
231
-    public String getSourceLine(final ProgramError error) {
232
-        for (String line : error.getTrace()) {
233
-            if (line.startsWith("com.dmdirc")) {
234
-                return line;
235
-            }
236
-        }
237
-
238
-        return error.getTrace().get(0);
239
-    }
240
-
241
-    /**
242
-     * Adds the specified error to the list of known errors and determines if it was previously
243
-     * added.
244
-     *
245
-     * @param error The error to be added
246
-     */
247
-    protected void addError(final ProgramError error) {
248
-        errors.add(error);
249
-    }
250
-
251
-    /**
252
-     * Determines whether or not the specified exception is one that we are willing to report.
253
-     *
254
-     * @param exception The exception to test
255
-     *
256
-     * @since 0.6.3m1
257
-     * @return True if the exception may be reported, false otherwise
258
-     */
259
-    protected boolean isValidError(final Throwable exception) {
260
-        Throwable target = exception;
261
-
262
-        while (target != null) {
263
-            for (Class<?> bad : BANNED_EXCEPTIONS) {
264
-                if (bad.equals(target.getClass())) {
265
-                    return false;
266
-                }
267
-            }
268
-
269
-            target = target.getCause();
270
-        }
271
-
272
-        return true;
273
-    }
274
-
275
-    /**
276
-     * Sends an error to the developers.
277
-     *
278
-     * @param error error to be sent
279
-     */
280
-    public void sendError(final ProgramError error) {
281
-        if (error.getReportStatus() != ErrorReportStatus.ERROR
282
-                && error.getReportStatus() != ErrorReportStatus.WAITING) {
283
-            return;
284
-        }
285
-        error.setReportStatus(ErrorReportStatus.QUEUED);
286
-
287
-        reportThread.submit(new ErrorReportingRunnable(sentryErrorReporter, error));
65
+    public Set<ProgramError> getErrors() {
66
+        return programErrorManager.getErrors();
288 67
     }
289 68
 
290
-    /**
291
-     * Called when an error needs to be deleted from the list.
292
-     *
293
-     * @param error ProgramError that changed
294
-     */
295 69
     public void deleteError(final ProgramError error) {
296
-        errors.remove(error);
297
-        eventBus.publish(new ProgramErrorDeletedEvent(error));
70
+        programErrorManager.deleteError(error);
298 71
     }
299 72
 
300
-    /**
301
-     * Deletes all errors from the manager.
302
-     *
303
-     * @since 0.6.3m1
304
-     */
305 73
     public void deleteAll() {
306
-        final Set<ProgramError> errorsCopy = Sets.newHashSet(errors);
307
-        errors.clear();
308
-        errorsCopy.forEach(e -> eventBus.publish(new ProgramErrorDeletedEvent(e)));
309
-    }
310
-
311
-    /**
312
-     * Returns the list of program errors.
313
-     *
314
-     * @return Program error list
315
-     */
316
-    public Set<ProgramError> getErrors() {
317
-        return Collections.unmodifiableSet(errors);
318
-    }
319
-
320
-    /**
321
-     * Fired when the program encounters an error.
322
-     *
323
-     * @param event Error that occurred
324
-     */
325
-    @Handler(priority = EventUtils.PRIORITY_LOWEST)
326
-    protected void fireErrorAdded(final NonFatalProgramErrorEvent event) {
327
-        if (!event.isHandled()) {
328
-            System.err.println("An error has occurred: " + event.getError().getLevel() + ": "
329
-                            + event.getError().getMessage());
330
-
331
-            for (String line : event.getError().getTrace()) {
332
-                System.err.println("\t" + line);
333
-            }
334
-        }
335
-    }
336
-
337
-    /**
338
-     * Fired when the program encounters a fatal error.
339
-     *
340
-     * @param event Error that occurred
341
-     */
342
-    @Handler(priority = EventUtils.PRIORITY_LOWEST)
343
-    protected void fireFatalError(final FatalProgramErrorEvent event) {
344
-        final boolean restart;
345
-        if (GraphicsEnvironment.isHeadless()) {
346
-            System.err.println("A fatal error has occurred: " + event.getError().getMessage());
347
-            for (String line : event.getError().getTrace()) {
348
-                System.err.println("\t" + line);
349
-            }
350
-            restart = false;
351
-        } else {
352
-            final FatalErrorDialog fed = new FatalErrorDialog(event.getError(), sentryErrorReporter,
353
-                    countDownLatch, sendReports);
354
-            fed.setVisible(true);
355
-            try {
356
-                countDownLatch.await();
357
-            } catch (InterruptedException ex) {
358
-                //Nevermind, carry on
359
-            }
360
-            restart = fed.getRestart();
361
-        }
362
-
363
-        if (restart) {
364
-            System.exit(42);
365
-        } else {
366
-            System.exit(1);
367
-        }
368
-    }
369
-
370
-    @ConfigBinding(domain = "general", key = "submitErrors")
371
-    public void handleSubmitErrors(final boolean value) {
372
-        submitReports = value;
373
-
374
-        sendReports = submitReports && !tempNoErrors;
375
-    }
376
-
377
-    @ConfigBinding(domain = "general", key="logerrors")
378
-    public void handleLogErrors(final boolean value) {
379
-        logReports = value;
380
-    }
381
-
382
-    @ConfigBinding(domain = "temp", key="noerrorreporting")
383
-    public void handleNoErrorReporting(final boolean value) {
384
-        tempNoErrors = value;
385
-        sendReports = submitReports && !tempNoErrors;
386
-    }
387
-
388
-    /**
389
-     * Returns this errors trace.
390
-     *
391
-     * @return Error trace
392
-     */
393
-    public List<String> getTrace(final String message, final Throwable exception) {
394
-        return Arrays.asList(exception == null ? message == null ? new String[0]
395
-                : new String[]{message} : getTrace(exception));
74
+        programErrorManager.deleteAll();
396 75
     }
397 76
 
398
-    /**
399
-     * Converts an exception into a string array.
400
-     *
401
-     * @param throwable Exception to convert
402
-     *
403
-     * @since 0.6.3m1
404
-     * @return Exception string array
405
-     */
406
-    private static String[] getTrace(final Throwable throwable) {
407
-        String[] trace;
408
-
409
-        if (throwable == null) {
410
-            trace = new String[0];
411
-        } else {
412
-            final StackTraceElement[] traceElements = throwable.getStackTrace();
413
-            trace = new String[traceElements.length + 1];
414
-
415
-            trace[0] = throwable.toString();
416
-
417
-            for (int i = 0; i < traceElements.length; i++) {
418
-                trace[i + 1] = traceElements[i].toString();
419
-            }
420
-
421
-            if (throwable.getCause() != null) {
422
-                final String[] causeTrace = getTrace(throwable.getCause());
423
-                final String[] newTrace = new String[trace.length + causeTrace.length];
424
-                trace[0] = "\nWhich caused: " + trace[0];
425
-
426
-                System.arraycopy(causeTrace, 0, newTrace, 0, causeTrace.length);
427
-                System.arraycopy(trace, 0, newTrace, causeTrace.length, trace.length);
428
-
429
-                trace = newTrace;
430
-            }
431
-        }
432
-
433
-        return trace;
434
-    }
435
-
436
-    private void saveError(final ProgramError error) {
437
-        if (directoryError) {
438
-            return;
439
-        }
440
-        final String logName = error.getDate().getTime() + "-" + error.getLevel();
441
-        final Path errorFile = errorsDirectory.resolve(logName + ".log");
442
-        final List<String> data = Lists.newArrayList("Date: " + error.getDate(),
443
-                "Level: " + error.getLevel(),
444
-                "Description: " + error.getMessage(),
445
-                "Details: ");
446
-        error.getTrace().forEach(line -> data.add('\t' + line));
447
-        try {
448
-            Files.write(errorFile, data, Charset.forName("UTF-8"));
449
-        } catch (IOException ex) {
450
-            //Not really anything we can do at this point, so don't try.
451
-        }
77
+    public void sendError(final ProgramError error) {
78
+        sentryLoggingErrorManager.sendError(error);
452 79
     }
453 80
 }

+ 12
- 12
src/com/dmdirc/logger/ProgramErrorManager.java Zobrazit soubor

@@ -30,12 +30,15 @@ import com.dmdirc.events.ProgramErrorEvent;
30 30
 import com.google.common.base.Throwables;
31 31
 
32 32
 import java.util.Arrays;
33
+import java.util.Collection;
33 34
 import java.util.Collections;
34 35
 import java.util.Date;
35 36
 import java.util.HashSet;
36
-import java.util.List;
37 37
 import java.util.Set;
38
-import java.util.concurrent.CopyOnWriteArrayList;
38
+import java.util.concurrent.CopyOnWriteArraySet;
39
+
40
+import javax.inject.Inject;
41
+import javax.inject.Singleton;
39 42
 
40 43
 import net.engio.mbassy.listener.Handler;
41 44
 
@@ -43,25 +46,22 @@ import net.engio.mbassy.listener.Handler;
43 46
  * Listens for {@link ErrorEvent}s, creates {@link ProgramError}s and raises {@link
44 47
  * ProgramErrorEvent}s.
45 48
  */
49
+@Singleton
46 50
 public class ProgramErrorManager {
47 51
 
48 52
     /** The event bus to listen for errors on. */
49 53
     private final DMDircMBassador eventBus;
50 54
     /** The current list of errors. */
51
-    private final List<ProgramError> errors;
55
+    private final Set<ProgramError> errors;
52 56
     /** Factory to create {@link ProgramError}s. */
53 57
     private final ProgramErrorFactory programErrorFactory;
54 58
 
55
-    /**
56
-     * Creates a new instance of this error manager.
57
-     *
58
-     * @param eventBus        The event bus to listen to errors on
59
-     */
59
+    @Inject
60 60
     public ProgramErrorManager(final DMDircMBassador eventBus,
61 61
             final ProgramErrorFactory programErrorFactory) {
62 62
         this.eventBus = eventBus;
63 63
         this.programErrorFactory = programErrorFactory;
64
-        errors = new CopyOnWriteArrayList<>();
64
+        errors = new CopyOnWriteArraySet<>();
65 65
     }
66 66
 
67 67
     /**
@@ -123,7 +123,7 @@ public class ProgramErrorManager {
123 123
      * @since 0.6.3m1
124 124
      */
125 125
     public void deleteAll() {
126
-        final Set<ProgramError> errorsCopy = new HashSet<>(errors);
126
+        final Collection<ProgramError> errorsCopy = new HashSet<>(errors);
127 127
         errors.clear();
128 128
         errorsCopy.stream().map(ProgramErrorDeletedEvent::new).forEach(eventBus::publish);
129 129
     }
@@ -133,7 +133,7 @@ public class ProgramErrorManager {
133 133
      *
134 134
      * @return Program error list
135 135
      */
136
-    public List<ProgramError> getErrors() {
137
-        return Collections.unmodifiableList(errors);
136
+    public Set<ProgramError> getErrors() {
137
+        return Collections.unmodifiableSet(errors);
138 138
     }
139 139
 }

+ 17
- 13
src/com/dmdirc/logger/SentryLoggingErrorManager.java Zobrazit soubor

@@ -26,17 +26,23 @@ import com.dmdirc.DMDircMBassador;
26 26
 import com.dmdirc.config.ConfigBinder;
27 27
 import com.dmdirc.config.ConfigBinding;
28 28
 import com.dmdirc.events.ProgramErrorEvent;
29
+import com.dmdirc.events.ProgramErrorStatusEvent;
29 30
 import com.dmdirc.interfaces.config.AggregateConfigProvider;
30 31
 
31 32
 import java.util.Collection;
32 33
 import java.util.Optional;
33 34
 import java.util.concurrent.ExecutorService;
34 35
 
36
+import javax.inject.Inject;
37
+import javax.inject.Named;
38
+import javax.inject.Singleton;
39
+
35 40
 import net.engio.mbassy.listener.Handler;
36 41
 
37 42
 /**
38 43
  * Listens for {@link ProgramErrorEvent}s and reports these to Sentry.
39 44
  */
45
+@Singleton
40 46
 public class SentryLoggingErrorManager {
41 47
 
42 48
     /** A list of exceptions which we don't consider bugs and thus don't report. */
@@ -47,8 +53,6 @@ public class SentryLoggingErrorManager {
47 53
             NoSuchFieldError.class,};
48 54
     /** The event bus to listen for errors on. */
49 55
     private final DMDircMBassador eventBus;
50
-    /** The config binder to use for settings. */
51
-    private final ConfigBinder configBinder;
52 56
     /** Sentry error reporter factory. */
53 57
     private final SentryErrorReporter sentryErrorReporter;
54 58
     /** Thread used for sending errors. */
@@ -60,25 +64,20 @@ public class SentryLoggingErrorManager {
60 64
     /** Whether or not to send error reports. */
61 65
     private boolean sendReports;
62 66
 
63
-    /**
64
-     * Creates a new instance of this error manager.
65
-     *
66
-     * @param eventBus        The event bus to listen to errors on
67
-     * @param config          The config to read values from
68
-     */
67
+    @Inject
69 68
     public SentryLoggingErrorManager(final DMDircMBassador eventBus,
70
-            final AggregateConfigProvider config, final SentryErrorReporter sentryErrorReporter,
71
-            final ExecutorService executorService) {
69
+            final SentryErrorReporter sentryErrorReporter,
70
+            @Named("singlethread") final ExecutorService executorService) {
72 71
         this.eventBus = eventBus;
73 72
         this.sentryErrorReporter = sentryErrorReporter;
74 73
         this.executorService = executorService;
75
-        configBinder = config.getBinder();
76 74
     }
77 75
 
78 76
     /**
79 77
      * Initialises the error manager.  Must be called before logging will start.
80 78
      */
81
-    public void initialise() {
79
+    public void initialise(final AggregateConfigProvider config) {
80
+        final ConfigBinder configBinder = config.getBinder();
82 81
         configBinder.bind(this, SentryLoggingErrorManager.class);
83 82
         eventBus.subscribe(this);
84 83
     }
@@ -90,11 +89,16 @@ public class SentryLoggingErrorManager {
90 89
                 || !isValidSource(error.getError().getTrace())
91 90
                 || !appError) {
92 91
             error.getError().setReportStatus(ErrorReportStatus.NOT_APPLICABLE);
92
+            eventBus.publish(new ProgramErrorStatusEvent(error.getError()));
93 93
         } else if (sendReports) {
94
-            executorService.submit(new ErrorReportingRunnable(sentryErrorReporter, error.getError()));
94
+            sendError(error.getError());
95 95
         }
96 96
     }
97 97
 
98
+    void sendError(final ProgramError error) {
99
+        executorService.submit(new ErrorReportingRunnable(sentryErrorReporter, error));
100
+    }
101
+
98 102
     @ConfigBinding(domain = "general", key = "submitErrors")
99 103
     void handleSubmitErrors(final boolean value) {
100 104
         submitReports = value;

+ 4
- 4
test/com/dmdirc/logger/DiskLoggingErrorManagerTest.java Zobrazit soubor

@@ -59,13 +59,13 @@ public class DiskLoggingErrorManagerTest {
59 59
     public void setUp() throws Exception {
60 60
         when(config.getBinder()).thenReturn(configBinder);
61 61
         fileSystem = Jimfs.newFileSystem(Configuration.unix());
62
-        instance = new DiskLoggingErrorManager(fileSystem.getPath("/errors"), eventBus, config);
62
+        instance = new DiskLoggingErrorManager(fileSystem.getPath("/errors"), eventBus);
63 63
     }
64 64
 
65 65
     @Test
66 66
     public void testInitialise() throws Exception {
67 67
         assertFalse(Files.exists(fileSystem.getPath("/errors")));
68
-        instance.initialise();
68
+        instance.initialise(config);
69 69
         verify(configBinder).bind(instance, DiskLoggingErrorManager.class);
70 70
         assertTrue(Files.exists(fileSystem.getPath("/errors")));
71 71
         assertFalse(instance.isDirectoryError());
@@ -80,7 +80,7 @@ public class DiskLoggingErrorManagerTest {
80 80
     public void testHandleErrorEvent() throws Exception {
81 81
         final UserErrorEvent error = new UserErrorEvent(ErrorLevel.MEDIUM,
82 82
                 new IllegalStateException(""), "", "");
83
-        instance.initialise();
83
+        instance.initialise(config);
84 84
         instance.handleLoggingSetting(true);
85 85
         final String logName = error.getTimestamp() + "-" + error.getLevel() + ".log";;
86 86
         assertFalse(Files.exists(fileSystem.getPath("/errors", logName)));
@@ -95,7 +95,7 @@ public class DiskLoggingErrorManagerTest {
95 95
         final UserErrorEvent error = new UserErrorEvent(ErrorLevel.MEDIUM,
96 96
                 new IllegalStateException(""),
97 97
                 "", "");
98
-        instance.initialise();
98
+        instance.initialise(config);
99 99
         instance.handleLoggingSetting(false);
100 100
         final String logName = error.getTimestamp() + "-" + error.getLevel() + ".log";;
101 101
         assertFalse(Files.exists(fileSystem.getPath("/errors", logName)));

+ 2
- 2
test/com/dmdirc/logger/SentryLoggingErrorManagerTest.java Zobrazit soubor

@@ -67,9 +67,9 @@ public class SentryLoggingErrorManagerTest {
67 67
         when(userErrorEvent.getError()).thenReturn(userError);
68 68
         when(userError.isAppError()).thenReturn(false);
69 69
         when(config.getBinder()).thenReturn(configBinder);
70
-        instance = new SentryLoggingErrorManager(eventBus, config, sentryErrorReporter,
70
+        instance = new SentryLoggingErrorManager(eventBus, sentryErrorReporter,
71 71
                 MoreExecutors.newDirectExecutorService());
72
-        instance.initialise();
72
+        instance.initialise(config);
73 73
         instance.handleSubmitErrors(true);
74 74
         instance.handleNoErrorReporting(false);
75 75
     }

Načítá se…
Zrušit
Uložit