38
38
@implementation RollbarNotifier
39
39
40
40
- (id )initWithAccessToken : (NSString *)accessToken configuration : (RollbarConfiguration*)configuration isRoot : (BOOL )isRoot {
41
-
41
+
42
42
if ((self = [super init ])) {
43
43
[self updateAccessToken: accessToken configuration: configuration isRoot: isRoot];
44
44
@@ -47,44 +47,48 @@ - (id)initWithAccessToken:(NSString*)accessToken configuration:(RollbarConfigura
47
47
NSString *cachesDirectory = [paths objectAtIndex: 0 ];
48
48
queuedItemsFilePath = [cachesDirectory stringByAppendingPathComponent: QUEUED_ITEMS_FILE_NAME];
49
49
stateFilePath = [cachesDirectory stringByAppendingPathComponent: STATE_FILE_NAME];
50
-
50
+
51
51
if (![[NSFileManager defaultManager ] fileExistsAtPath: queuedItemsFilePath]) {
52
52
[[NSFileManager defaultManager ] createFileAtPath: queuedItemsFilePath contents: nil attributes: nil ];
53
53
}
54
-
54
+
55
55
if ([[NSFileManager defaultManager ] fileExistsAtPath: stateFilePath]) {
56
56
NSData *stateData = [NSData dataWithContentsOfFile: stateFilePath];
57
- NSDictionary *state = [NSJSONSerialization JSONObjectWithData: stateData options: 0 error: nil ];
58
-
59
- queueState = [state mutableCopy ];
60
- } else {
57
+ if (stateData) {
58
+ NSDictionary *state = [NSJSONSerialization JSONObjectWithData: stateData options: 0 error: nil ];
59
+ queueState = [state mutableCopy ];
60
+ } else {
61
+ RollbarLog (@" There was an error restoring saved queue state" );
62
+ }
63
+ }
64
+ if (!queueState) {
61
65
queueState = [@{@" offset" : [NSNumber numberWithUnsignedInt: 0 ],
62
66
@" retry_count" : [NSNumber numberWithUnsignedInt: 0 ]} mutableCopy];
63
67
}
64
-
68
+
65
69
// Deals with sending items that have been queued up
66
70
rollbarThread = [[RollbarThread alloc ] initWithNotifier: self ];
67
71
[rollbarThread start ];
68
-
72
+
69
73
// Listen for reachability status so that items are only sent when the internet is available
70
74
reachability = [RollbarReachability reachabilityForInternetConnection ];
71
-
75
+
72
76
isNetworkReachable = [reachability isReachable ];
73
-
77
+
74
78
reachability.reachableBlock = ^(RollbarReachability*reach) {
75
79
[self captureTelemetryDataForNetwork: true ];
76
80
isNetworkReachable = YES ;
77
81
};
78
-
82
+
79
83
reachability.unreachableBlock = ^(RollbarReachability*reach) {
80
84
[self captureTelemetryDataForNetwork: false ];
81
85
isNetworkReachable = NO ;
82
86
};
83
-
87
+
84
88
[reachability startNotifier ];
85
89
}
86
90
}
87
-
91
+
88
92
return self;
89
93
}
90
94
@@ -112,71 +116,76 @@ - (void)processSavedItems {
112
116
// Don't attempt sending if the network is known to be not reachable
113
117
return ;
114
118
}
115
-
119
+
116
120
__block NSString *lastAccessToken = nil ;
117
121
NSMutableArray *items = [NSMutableArray array ];
118
122
119
123
NSUInteger startOffset = [queueState[@" offset" ] unsignedIntegerValue ];
120
-
124
+
121
125
NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingAtPath: queuedItemsFilePath];
122
126
[fileHandle seekToEndOfFile ];
123
127
__block unsigned long long fileLength = [fileHandle offsetInFile ];
124
128
[fileHandle closeFile ];
125
-
129
+
126
130
if (!fileLength) {
127
131
return ;
128
132
}
129
-
133
+
130
134
// Empty out the queued item file if all items have been processed already
131
135
if (startOffset == fileLength) {
132
136
[@" " writeToFile: queuedItemsFilePath atomically: YES encoding: NSUTF8StringEncoding error: nil ];
133
-
137
+
134
138
queueState[@" offset" ] = [NSNumber numberWithUnsignedInteger: 0 ];
135
139
queueState[@" retry_count" ] = [NSNumber numberWithUnsignedInteger: 0 ];
136
140
[self saveQueueState ];
137
-
141
+
138
142
return ;
139
143
}
140
-
144
+
141
145
// Iterate through the items file and send the items in batches.
142
146
RollbarFileReader *reader = [[RollbarFileReader alloc ] initWithFilePath: queuedItemsFilePath andOffset: startOffset];
143
147
[reader enumerateLinesUsingBlock: ^(NSString *line, NSUInteger nextOffset, BOOL *stop) {
144
- NSDictionary *payload = [NSJSONSerialization JSONObjectWithData: [line dataUsingEncoding: NSUTF8StringEncoding] options: 0 error: nil ];
145
-
148
+ NSData *lineData = [line dataUsingEncoding: NSUTF8StringEncoding];
149
+ if (!lineData) {
150
+ // All we can do is ignore this line
151
+ RollbarLog (@" Error converting file line to NSData" );
152
+ return ;
153
+ }
154
+ NSDictionary *payload = [NSJSONSerialization JSONObjectWithData: lineData options: 0 error: nil ];
155
+
146
156
if (!payload) {
147
157
// Ignore this line if it isn't valid json and proceed to the next line
148
- // TODO: report an internal error
158
+ RollbarLog ( @" Error restoring data from file to JSON " );
149
159
return ;
150
160
}
151
-
161
+
152
162
NSString *accessToken = payload[@" access_token" ];
153
-
163
+
154
164
// If the max batch size is reached as the file is being processed,
155
165
// try sending the current batch before starting a new one
156
166
if ([items count ] >= MAX_BATCH_SIZE || (lastAccessToken != nil && [accessToken compare: lastAccessToken] != NSOrderedSame)) {
157
167
BOOL shouldContinue = [self sendItems: items withAccessToken: lastAccessToken nextOffset: nextOffset];
158
-
168
+
159
169
if (!shouldContinue) {
160
170
// Stop processing the file so that the current file offset will be
161
171
// retried next time the file is processed
162
172
*stop = YES ;
163
173
return ;
164
174
}
165
-
175
+
166
176
// The file has had items added since we started iterating through it,
167
177
// update the known file length to equal the next offset
168
178
if (nextOffset > fileLength) {
169
179
fileLength = nextOffset;
170
180
}
171
-
181
+
172
182
[items removeAllObjects ];
173
183
}
174
-
175
184
[items addObject: payload[@" data" ]];
176
-
185
+
177
186
lastAccessToken = accessToken;
178
187
}];
179
-
188
+
180
189
// The whole file has been read, send all of the pending items
181
190
if ([items count ]) {
182
191
[self sendItems: items withAccessToken: lastAccessToken nextOffset: (NSUInteger )fileLength];
@@ -482,7 +491,9 @@ - (BOOL)checkPayloadResponse:(NSURLResponse*)response error:(NSError*)error data
482
491
return YES ;
483
492
} else {
484
493
RollbarLog (@" There was a problem reporting to Rollbar" );
485
- RollbarLog (@" Response: %@ " , [NSJSONSerialization JSONObjectWithData: data options: 0 error: nil ]);
494
+ if (data) {
495
+ RollbarLog (@" Response: %@ " , [NSJSONSerialization JSONObjectWithData: data options: 0 error: nil ]);
496
+ }
486
497
}
487
498
}
488
499
return NO ;
0 commit comments