core-native
Version:
A lightweight framework based on React Native + Redux + Redux Saga, in strict TypeScript.
142 lines • 5.19 kB
JavaScript
import { loggerContext } from "./platform/logger-context";
import { errorToException } from "./util/error-util";
import { app } from "./app";
import { APIException, JavaScriptException, NetworkConnectionException } from "./Exception";
export class LoggerImpl {
constructor() {
this.contextMap = {};
this.logQueue = [];
this.collectPosition = 0;
this.contextMap = loggerContext;
}
addContext(context) {
const newContextMap = Object.assign(Object.assign({}, this.contextMap), context);
const contextSize = Object.keys(newContextMap).length;
if (contextSize > 20) {
console.warn(`[framework] Logger context size ${contextSize} is too large`);
}
this.contextMap = newContextMap;
}
removeContext(key) {
if (this.contextMap[key] !== undefined) {
delete this.contextMap[key];
}
else {
console.warn(`[framework] Logger context key ${key} does not exist`);
}
}
info(entry) {
this.createLog("OK", entry);
}
warn(entry) {
this.createLog("WARN", entry);
}
error(entry) {
this.createLog("ERROR", entry);
}
exception(exception, extraInfo, action) {
let isWarning;
let errorCode;
const info = Object.assign({}, extraInfo);
if (exception instanceof NetworkConnectionException) {
isWarning = true;
errorCode = "NETWORK_FAILURE";
info["api_url"] = exception.requestURL;
info["original_message"] = exception.originalErrorMessage;
}
else if (exception instanceof APIException) {
if (exception.statusCode === 400 && exception.errorCode === "VALIDATION_ERROR") {
isWarning = false;
errorCode = "API_VALIDATION_ERROR";
}
else {
isWarning = true;
errorCode = `API_ERROR_${exception.statusCode}`;
}
info["api_url"] = exception.requestURL;
info["api_response"] = JSON.stringify(exception.responseData);
if (exception.errorId) {
info["api_error_id"] = exception.errorId;
}
if (exception.errorCode) {
info["api_error_code"] = exception.errorCode;
}
}
else if (exception instanceof JavaScriptException) {
isWarning = false;
errorCode = "JAVASCRIPT_ERROR";
info["app_state"] = JSON.stringify(app.store.getState().app);
}
else {
console.warn("[framework] Exception class should not be extended, throw Error instead");
isWarning = false;
errorCode = "JAVASCRIPT_ERROR";
}
this.createLog(isWarning ? "WARN" : "ERROR", { action, errorCode, errorMessage: exception.message, info, elapsedTime: 0 });
}
collect(maxSize = 0) {
const totalLength = this.logQueue.length;
if (maxSize > 0 && maxSize < totalLength) {
this.collectPosition = maxSize;
return this.logQueue.slice(0, maxSize);
}
else {
this.collectPosition = totalLength;
return this.logQueue;
}
}
emptyLastCollection() {
this.logQueue = this.logQueue.slice(this.collectPosition);
}
createLog(result, entry) {
// Generate context
const context = {};
Object.entries(this.contextMap).map(([key, value]) => {
if (typeof value === "string") {
context[key] = value.substr(0, 1000);
}
else {
try {
context[key] = value();
}
catch (e) {
const message = errorToException(e).message;
context[key] = "ERR# " + message;
console.warn("[framework] Fail to execute logger context: " + message);
}
}
});
// Generate info
const info = {};
if (entry.info) {
Object.entries(entry.info).map(([key, value]) => {
if (value !== undefined) {
const isBuiltinInfo = ["app_state", "stacktrace", "extra_stacktrace"].includes(key);
info[key] = isBuiltinInfo ? value.substr(0, 500000) : value.substr(0, 500);
}
});
}
// Generate stats
const stats = {};
if (entry.stats) {
Object.entries(entry.stats).map(([key, value]) => {
if (value !== undefined) {
stats[key] = value;
}
});
}
const event = {
date: new Date(),
action: entry.action,
elapsedTime: entry.elapsedTime || 0,
result,
context,
info,
stats,
errorCode: "errorCode" in entry ? entry.errorCode : undefined,
errorMessage: "errorMessage" in entry ? entry.errorMessage.substr(0, 1000) : undefined,
};
this.logQueue.push(event);
}
}
//# sourceMappingURL=Logger.js.map