Skip to content

Commit e3f7b79

Browse files
committed
ensure protocol safety
1 parent 63f867d commit e3f7b79

File tree

8 files changed

+482
-371
lines changed

8 files changed

+482
-371
lines changed

dist/logline.js

Lines changed: 246 additions & 191 deletions
Large diffs are not rendered by default.

dist/logline.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/logline.min.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "logline",
3-
"version": "1.0.9",
3+
"version": "1.0.12",
44
"description": "logs for the frontend",
55
"main": "dist/logline.min.js",
66
"scripts": {

src/logline.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,12 @@ class Logline {
1616
if (!(this instanceof Logline)) {
1717
return new Logline(namespace);
1818
}
19-
Logline._checkProtocol();
20-
return new Logline._protocol(namespace);
19+
try {
20+
Logline._checkProtocol();
21+
return new Logline._protocol(namespace);
22+
} catch (e) {
23+
return new Interface(namespace);
24+
}
2125
}
2226

2327
/**
@@ -51,7 +55,7 @@ class Logline {
5155
}
5256
}
5357

54-
throw new Error(protocols.join(', ').toLowerCase() + ' protocols are not supported on this platform');
58+
util.throwError('protocols ' + protocols.join(', ').toLowerCase() + ' are not supported on this platform');
5559
}
5660
}
5761

src/protocols/indexeddb.js

Lines changed: 159 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -25,33 +25,37 @@ export default class IndexedDBLogger extends LoggerInterface {
2525
* @param {Mixed} [data] - additional data
2626
*/
2727
_record(level, descriptor, data) {
28-
if (IndexedDBLogger.status !== LoggerInterface.STATUS.INITED) {
29-
IndexedDBLogger._pool.push(() => this._record(level, descriptor, data));
30-
if (IndexedDBLogger.status !== LoggerInterface.STATUS.INITING) {
31-
IndexedDBLogger.init();
28+
try {
29+
if (IndexedDBLogger.status !== LoggerInterface.STATUS.INITED) {
30+
IndexedDBLogger._pool.push(() => this._record(level, descriptor, data));
31+
if (IndexedDBLogger.status !== LoggerInterface.STATUS.INITING) {
32+
IndexedDBLogger.init();
33+
}
34+
return;
3235
}
33-
return;
34-
}
3536

36-
util.debug(this._namespace, level, descriptor, data);
37-
let transaction = IndexedDBLogger.db.transaction(['logs'], IDBTransaction.READ_WRITE || 'readwrite');
38-
transaction.onerror = event => util.throwError(event.target.error);
39-
40-
let store = transaction.objectStore('logs');
41-
// should not contains any function in data
42-
// otherwise 'DOMException: Failed to execute 'add' on 'IDBObjectStore': An object could not be cloned.' will be thrown
43-
let request = store.add({
44-
time: Date.now(),
45-
level: level,
46-
namespace: this._namespace,
47-
descriptor: descriptor,
48-
data: util.filterFunction(data)
49-
});
50-
51-
request.onerror = event => {
52-
IndexedDBLogger.status = LoggerInterface.STATUS.FAILED;
53-
util.throwError(event.target.error);
54-
};
37+
util.debug(this._namespace, level, descriptor, data);
38+
let transaction = IndexedDBLogger.db.transaction(['logs'], IDBTransaction.READ_WRITE || 'readwrite');
39+
transaction.onerror = event => util.throwError(event.target.error);
40+
41+
let store = transaction.objectStore('logs');
42+
// should not contains any function in data
43+
// otherwise 'DOMException: Failed to execute 'add' on 'IDBObjectStore': An object could not be cloned.' will be thrown
44+
let request = store.add({
45+
time: Date.now(),
46+
level: level,
47+
namespace: this._namespace,
48+
descriptor: descriptor,
49+
data: util.filterFunction(data)
50+
});
51+
52+
request.onerror = event => {
53+
IndexedDBLogger.status = LoggerInterface.STATUS.FAILED;
54+
util.throwError(event.target.error);
55+
};
56+
} catch (e) {
57+
util.throwError('failed to write, ' + e.message);
58+
}
5559
}
5660

5761
/**
@@ -61,35 +65,39 @@ export default class IndexedDBLogger extends LoggerInterface {
6165
* @param {String} database - database name to use
6266
*/
6367
static init(database) {
64-
if (!IndexedDBLogger.support) {
65-
util.throwError('your platform does not support indexeddb protocol.');
66-
}
68+
try {
69+
if (!IndexedDBLogger.support) {
70+
util.throwError('your platform does not support indexeddb protocol.');
71+
}
6772

68-
if (IndexedDBLogger.status) {
69-
return false;
70-
}
73+
if (IndexedDBLogger.status) {
74+
return false;
75+
}
76+
77+
IndexedDBLogger._pool = IndexedDBLogger._pool || new Pool();
78+
IndexedDBLogger._database = database || 'logline';
79+
IndexedDBLogger.status = super.STATUS.INITING;
7180

72-
IndexedDBLogger._pool = IndexedDBLogger._pool || new Pool();
73-
IndexedDBLogger._database = database || 'logline';
74-
IndexedDBLogger.status = super.STATUS.INITING;
75-
76-
IndexedDBLogger.request = window.indexedDB.open(IndexedDBLogger._database);
77-
IndexedDBLogger.request.onerror = event => util.throwError('protocol indexeddb is prevented.');
78-
IndexedDBLogger.request.onsuccess = event => {
79-
IndexedDBLogger.db = event.target.result;
80-
IndexedDBLogger.status = super.STATUS.INITED;
81-
IndexedDBLogger._pool.consume();
82-
// globally handle db request errors
83-
IndexedDBLogger.db.onerror = event => util.throwError(event.target.error);
84-
};
85-
IndexedDBLogger.request.onupgradeneeded = event => {
86-
// init dabasebase
87-
let db = event.target.result, store = db.createObjectStore('logs', { autoIncrement: true });
88-
store.createIndex('namespace', 'namespace', { unique: false });
89-
store.createIndex('level', 'level', { unique: false });
90-
store.createIndex('descriptor', 'descriptor', { unique: false });
91-
store.createIndex('data', 'data', { unique: false });
92-
};
81+
IndexedDBLogger.request = window.indexedDB.open(IndexedDBLogger._database);
82+
IndexedDBLogger.request.onerror = event => util.throwError('protocol indexeddb is prevented.');
83+
IndexedDBLogger.request.onsuccess = event => {
84+
IndexedDBLogger.db = event.target.result;
85+
IndexedDBLogger.status = super.STATUS.INITED;
86+
IndexedDBLogger._pool.consume();
87+
// globally handle db request errors
88+
IndexedDBLogger.db.onerror = event => util.throwError(event.target.error);
89+
};
90+
IndexedDBLogger.request.onupgradeneeded = event => {
91+
// init dabasebase
92+
let db = event.target.result, store = db.createObjectStore('logs', { autoIncrement: true });
93+
store.createIndex('namespace', 'namespace', { unique: false });
94+
store.createIndex('level', 'level', { unique: false });
95+
store.createIndex('descriptor', 'descriptor', { unique: false });
96+
store.createIndex('data', 'data', { unique: false });
97+
};
98+
} catch (e) {
99+
util.throwError('failed init, ' + e.message);
100+
}
93101
}
94102

95103
/**
@@ -102,50 +110,57 @@ export default class IndexedDBLogger extends LoggerInterface {
102110
* @param {Function} readyFn - function to call back with logs as parameter
103111
*/
104112
static get(from, to, readyFn) {
105-
if (IndexedDBLogger.status !== super.STATUS.INITED) {
106-
return IndexedDBLogger._pool.push(() => IndexedDBLogger.get(from, to, readyFn));
107-
}
113+
try {
114+
if (IndexedDBLogger.status !== super.STATUS.INITED) {
115+
return IndexedDBLogger._pool.push(() => IndexedDBLogger.get(from, to, readyFn));
116+
}
108117

109-
from = LoggerInterface.transTimeFormat(from);
110-
to = LoggerInterface.transTimeFormat(to);
118+
from = LoggerInterface.transTimeFormat(from);
119+
to = LoggerInterface.transTimeFormat(to);
111120

112-
let store = IndexedDBLogger._getTransactionStore(IDBTransaction.READ_ONLY);
121+
let store = IndexedDBLogger._getTransactionStore(IDBTransaction.READ_ONLY);
122+
if (!store) {
123+
return readyFn([]);
124+
}
113125

114-
// IDBObjectStore.getAll is a non-standard API
115-
if (store.getAll) {
116-
let result, logs = [];
117-
store.getAll().onsuccess = event => {
118-
result = event.target.result;
119-
for (let i = 0; i < result.length; i++) {
120-
if ((from && result[i].time < from) || (to && result[i].time > to)) {
121-
continue;
126+
// IDBObjectStore.getAll is a non-standard API
127+
if (store.getAll) {
128+
let result, logs = [];
129+
store.getAll().onsuccess = event => {
130+
result = event.target.result;
131+
for (let i = 0; i < result.length; i++) {
132+
if ((from && result[i].time < from) || (to && result[i].time > to)) {
133+
continue;
134+
}
135+
logs.push(result[i]);
122136
}
123-
logs.push(result[i]);
124-
}
125-
readyFn(logs);
126-
};
127-
} else {
128-
let request = store.openCursor(), logs = [];
129-
request.onsuccess = event => {
130-
var cursor = event.target.result;
131-
if (cursor) {
132-
if ((from && cursor.value.time < from) || (to && cursor.value.time > to)) {
133-
return cursor.continue();
134-
}
135-
136-
logs.push({
137-
time: cursor.value.time,
138-
level: cursor.value.level,
139-
namespace: cursor.value.namespace,
140-
descriptor: cursor.value.descriptor,
141-
data: cursor.value.data
142-
});
143-
cursor.continue();
144-
}
145-
else {
146137
readyFn(logs);
147-
}
148-
};
138+
};
139+
} else {
140+
let request = store.openCursor(), logs = [];
141+
request.onsuccess = event => {
142+
var cursor = event.target.result;
143+
if (cursor) {
144+
if ((from && cursor.value.time < from) || (to && cursor.value.time > to)) {
145+
return cursor.continue();
146+
}
147+
148+
logs.push({
149+
time: cursor.value.time,
150+
level: cursor.value.level,
151+
namespace: cursor.value.namespace,
152+
descriptor: cursor.value.descriptor,
153+
data: cursor.value.data
154+
});
155+
cursor.continue();
156+
}
157+
else {
158+
readyFn(logs);
159+
}
160+
};
161+
}
162+
} catch (e) {
163+
util.throwError('failed to get logs, ' + e.message);
149164
}
150165
}
151166

@@ -156,25 +171,32 @@ export default class IndexedDBLogger extends LoggerInterface {
156171
* @param {Number} daysToMaintain - keep logs within days
157172
*/
158173
static keep(daysToMaintain) {
159-
if (IndexedDBLogger.status !== super.STATUS.INITED) {
160-
return IndexedDBLogger._pool.push(() => IndexedDBLogger.keep(daysToMaintain));
161-
}
174+
try {
175+
if (IndexedDBLogger.status !== super.STATUS.INITED) {
176+
return IndexedDBLogger._pool.push(() => IndexedDBLogger.keep(daysToMaintain));
177+
}
162178

163-
let store = IndexedDBLogger._getTransactionStore(IDBTransaction.READ_WRITE);
164-
if (!daysToMaintain) {
165-
let request = store.clear().onerror = event => util.throwError(event.target.error);
166-
}
167-
else {
168-
let range = (Date.now() - (daysToMaintain || 2) * 24 * 3600 * 1000);
169-
let request = store.openCursor();
170-
request.onsuccess = event => {
171-
let cursor = event.target.result;
172-
if (cursor && cursor.value.time < range) {
173-
store.delete(cursor.primaryKey);
174-
cursor.continue();
175-
}
176-
};
177-
request.onerror = event => util.throwError('unable to locate logs earlier than ' + daysToMaintain + 'd.');
179+
let store = IndexedDBLogger._getTransactionStore(IDBTransaction.READ_WRITE);
180+
if (!store) {
181+
return false;
182+
}
183+
if (!daysToMaintain) {
184+
let request = store.clear().onerror = event => util.throwError(event.target.error);
185+
}
186+
else {
187+
let range = (Date.now() - (daysToMaintain || 2) * 24 * 3600 * 1000);
188+
let request = store.openCursor();
189+
request.onsuccess = event => {
190+
let cursor = event.target.result;
191+
if (cursor && cursor.value.time < range) {
192+
store.delete(cursor.primaryKey);
193+
cursor.continue();
194+
}
195+
};
196+
request.onerror = event => util.throwError('unable to locate logs earlier than ' + daysToMaintain + 'd.');
197+
}
198+
} catch (e) {
199+
util.throwError('failed to keep logs, ' + e.message);
178200
}
179201
}
180202

@@ -184,19 +206,23 @@ export default class IndexedDBLogger extends LoggerInterface {
184206
* @static
185207
*/
186208
static clean() {
187-
if (IndexedDBLogger.status !== super.STATUS.INITED) {
188-
return IndexedDBLogger._pool.push(() => IndexedDBLogger.clean());
189-
}
209+
try {
210+
if (IndexedDBLogger.status !== super.STATUS.INITED) {
211+
return IndexedDBLogger._pool.push(() => IndexedDBLogger.clean());
212+
}
190213

191-
// database can be removed only after all connections are closed
192-
IndexedDBLogger.db.close();
193-
let request = window.indexedDB.deleteDatabase(IndexedDBLogger._database);
194-
request.onerror = event => util.throwError(event.target.error);
195-
/* eslint no-unused-vars: "off" */
196-
request.onsuccess = event => {
197-
delete IndexedDBLogger.status;
198-
delete IndexedDBLogger.db;
199-
};
214+
// database can be removed only after all connections are closed
215+
IndexedDBLogger.db.close();
216+
let request = window.indexedDB.deleteDatabase(IndexedDBLogger._database);
217+
request.onerror = event => util.throwError(event.target.error);
218+
/* eslint no-unused-vars: "off" */
219+
request.onsuccess = event => {
220+
delete IndexedDBLogger.status;
221+
delete IndexedDBLogger.db;
222+
};
223+
} catch (e) {
224+
util.throwError('failed to cleanup logs, ' + e.message);
225+
}
200226
}
201227

202228
/**
@@ -208,13 +234,18 @@ export default class IndexedDBLogger extends LoggerInterface {
208234
* @return {Object} - internal object store
209235
*/
210236
static _getTransactionStore(mode) {
211-
if (IndexedDBLogger.db) {
212-
let transaction = IndexedDBLogger.db.transaction(['logs'], mode || IDBTransaction.READ_WRITE);
213-
transaction.onerror = event => util.throwError(event.target.error);
214-
return transaction.objectStore('logs');
215-
}
216-
else {
217-
util.throwError('log database is not created or connections are closed, considering init it.');
237+
try {
238+
if (IndexedDBLogger.db) {
239+
let transaction = IndexedDBLogger.db.transaction(['logs'], mode || IDBTransaction.READ_WRITE);
240+
transaction.onerror = event => util.throwError(event.target.error);
241+
return transaction.objectStore('logs');
242+
}
243+
else {
244+
util.throwError('log database is not created or connections are closed, considering init it.');
245+
}
246+
} catch (e) {
247+
util.throwError('failed to generate new transaction, ' + e.message);
248+
return false;
218249
}
219250
}
220251

0 commit comments

Comments
 (0)