UNPKG

core-native

Version:

A lightweight framework based on React Native + Redux + Redux Saga, in strict TypeScript.

142 lines 5.19 kB
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