diff --git a/arkguard/src/ArkObfuscator.ts b/arkguard/src/ArkObfuscator.ts index 045ee1492135332d43459c9baa5b7b15d081e345..3a8159c7486565345a623e44ab7a32978cc8cdbd 100644 --- a/arkguard/src/ArkObfuscator.ts +++ b/arkguard/src/ArkObfuscator.ts @@ -81,6 +81,7 @@ export { startSingleFileEvent, } from './utils/PrinterUtils'; import { Extension, type ProjectInfo, type FilePathObj } from './common/type'; +export { type HvigorErrorInfo } from './common/type'; export { FileUtils } from './utils/FileUtils'; export { MemoryUtils } from './utils/MemoryUtils'; import { TypeUtils } from './utils/TypeUtils'; diff --git a/arkguard/src/common/type.ts b/arkguard/src/common/type.ts index daf787dabe2124e5acefbf51718ba6b93be900a7..2d988379e1c2f43b5a358371ee0c82414939ab28 100644 --- a/arkguard/src/common/type.ts +++ b/arkguard/src/common/type.ts @@ -63,4 +63,14 @@ export const supportedDeclarationExtension: readonly string[] = [Extension.DTS, export const fileExtensions: string[] = [Extension.DETS, Extension.ETS, Extension.DTS, Extension.TS, Extension.JS, Extension.JSON]; // supported file suffixes from ets-loader. -export const supportedParsingExtension: string[] = [Extension.ETS, Extension.TS, Extension.JS, Extension.CJS, Extension.MJS]; \ No newline at end of file +export const supportedParsingExtension: string[] = [Extension.ETS, Extension.TS, Extension.JS, Extension.CJS, Extension.MJS]; + +// Formatted Error Info for hvigor +export interface HvigorErrorInfo { + code: string; + description: string; + cause: string; + position: string; + solutions: string[]; + moreInfo?: Object; +} \ No newline at end of file diff --git a/arkguard/src/initialization/ConfigResolver.ts b/arkguard/src/initialization/ConfigResolver.ts index 8e93f45f4fe08b8280f3911fe8f2fa9a276cb8ed..b2798f53943aa832d069f4c5b802ebc07948fd86 100644 --- a/arkguard/src/initialization/ConfigResolver.ts +++ b/arkguard/src/initialization/ConfigResolver.ts @@ -43,6 +43,7 @@ import { WhitelistType } from '../utils/TransformUtil'; import { endFilesEvent, startFilesEvent } from '../utils/PrinterUtils'; import { MemoryDottingDefine } from '../utils/MemoryDottingDefine'; import { initScanProjectConfigByMergeConfig, scanProjectConfig, resetScanProjectConfig } from '../common/ApiReader'; +import type { HvigorErrorInfo } from '../common/type'; enum OptionType { NONE, @@ -193,14 +194,14 @@ export class MergedConfig { export class ObConfigResolver { sourceObConfig: any; - logger: any; + printObfLogger: Function; isHarCompiled: boolean | undefined; isHspCompiled: boolean | undefined; isTerser: boolean; - constructor(projectConfig: any, logger: any, isTerser?: boolean) { + constructor(projectConfig: any, printObfLogger: Function, isTerser?: boolean) { this.sourceObConfig = projectConfig.obfuscationOptions; - this.logger = logger; + this.printObfLogger = printObfLogger; this.isHarCompiled = projectConfig.compileHar; this.isHspCompiled = projectConfig.compileShared; this.isTerser = isTerser; @@ -287,8 +288,15 @@ export class ObConfigResolver { try { fileContent = fs.readFileSync(path, 'utf-8'); } catch (err) { - this.logger.error(`Failed to open ${path}. Error message: ${err}`); - throw err; + const errorInfo = `Failed to open ${path}. Error message: ${err}`; + const errorCodeInfo: HvigorErrorInfo = { + code: '10804001', + description: 'ArkTS compiler Error', + cause: `Failed to open obfuscation config file from ${path}. Error message: ${err}`, + position: path, + solutions: [`Please check whether ${path} exists.`], + }; + this.printObfLogger(errorInfo, errorCodeInfo, 'error'); } this.handleConfigContent(fileContent, configs, path); } @@ -630,7 +638,8 @@ export class ObConfigResolver { } if (!fs.existsSync(tempAbsPath)) { - this.logger.warn(yellow + 'ArkTS: The path of obfuscation \'-keep\' configuration does not exist: ' + keepPath); + const warnInfo: string = `ArkTS: The path of obfuscation \'-keep\' configuration does not exist: ${keepPath}`; + this.printObfLogger(warnInfo, warnInfo, 'warn'); continue; } tempAbsPath = fs.realpathSync(tempAbsPath); @@ -860,7 +869,15 @@ export class ObConfigResolver { private determineNameCachePath(nameCachePath: string, configPath: string): void { if (!fs.existsSync(nameCachePath)) { - throw new Error(`The applied namecache file '${nameCachePath}' configured by '${configPath}' does not exist.`); + const errorInfo: string = `The applied namecache file '${nameCachePath}' configured by '${configPath}' does not exist.`; + const errorCodeInfo: HvigorErrorInfo = { + code: '10804004', + description: 'ArkTS compiler Error', + cause: `The applied namecache file '${nameCachePath}' configured by '${configPath}' does not exist.`, + position: configPath, + solutions: [`Please check ${configPath} and make sure the file configured by -apply-namecache exists`], + }; + this.printObfLogger(errorInfo, errorCodeInfo, 'error'); } } } @@ -928,7 +945,7 @@ export function collectResevedFileNameInIDEConfig( return reservedFileNames; } -export function readNameCache(nameCachePath: string, logger: any): void { +export function readNameCache(nameCachePath: string, printObfLogger: Function): void { try { const fileContent = fs.readFileSync(nameCachePath, 'utf-8'); const nameCache: { @@ -949,7 +966,15 @@ export function readNameCache(nameCachePath: string, logger: any): void { nameCacheMap.set(key, rest[key]); }); } catch (err) { - logger.error(`Failed to open ${nameCachePath}. Error message: ${err}`); + const errorInfo: string = `Failed to open ${nameCachePath}. Error message: ${err}`; + const errorCodeInfo: HvigorErrorInfo = { + code: '10804002', + description: 'ArkTS compiler Error', + cause: `Failed to open namecache file from ${nameCachePath}, Error message: ${err}`, + position: nameCachePath, + solutions: [`Please check ${nameCachePath} as error message suggested.`], + }; + printObfLogger(errorInfo, errorCodeInfo, 'error'); } } @@ -1208,9 +1233,9 @@ export function printUnobfuscationReasons(configPath: string, defaultPath: strin } -export function generateConsumerObConfigFile(obfuscationOptions: any, logger: any): void { +export function generateConsumerObConfigFile(obfuscationOptions: any, printObfLogger: Function): void { const projectConfig = { obfuscationOptions, compileHar: true }; - const obConfig: ObConfigResolver = new ObConfigResolver(projectConfig, logger); + const obConfig: ObConfigResolver = new ObConfigResolver(projectConfig, printObfLogger); obConfig.resolveObfuscationConfigs(); } diff --git a/arkguard/src/initialization/Initializer.ts b/arkguard/src/initialization/Initializer.ts index b168d420b494ce43a27c25b97c5aabba9a507bde..6608f2e3d0a0773ebfeffaff2eb798d8afbe4629 100644 --- a/arkguard/src/initialization/Initializer.ts +++ b/arkguard/src/initialization/Initializer.ts @@ -19,6 +19,7 @@ import path from 'path'; import { ArkObfuscator, blockPrinter, renameIdentifierModule } from '../ArkObfuscator'; import { collectResevedFileNameInIDEConfig, MergedConfig, ObConfigResolver, readNameCache } from './ConfigResolver'; import { type IOptions } from '../configs/IOptions'; +import type { HvigorErrorInfo } from '../common/type'; // Record all unobfuscated properties and reasons. export let historyUnobfuscatedPropMap: Map | undefined; @@ -35,8 +36,8 @@ export const printerConfig = { mOutputPath: '', }; -export function initObfuscationConfig(projectConfig: any, arkProjectConfig: any, logger: any): void { - const obConfig: ObConfigResolver = new ObConfigResolver(projectConfig, logger, true); +export function initObfuscationConfig(projectConfig: any, arkProjectConfig: any, printObfLogger: Function): void { + const obConfig: ObConfigResolver = new ObConfigResolver(projectConfig, printObfLogger, true); const mergedObConfig: MergedConfig = obConfig.resolveObfuscationConfigs(); const isHarCompiled: boolean = projectConfig.compileHar; if (mergedObConfig.options.disableObfuscation) { @@ -59,7 +60,7 @@ export function initObfuscationConfig(projectConfig: any, arkProjectConfig: any, arkProjectConfig.arkObfuscator = initArkGuardConfig( projectConfig.obfuscationOptions?.obfuscationCacheDir, - logger, + printObfLogger, mergedObConfig, isHarCompiled, ); @@ -67,7 +68,7 @@ export function initObfuscationConfig(projectConfig: any, arkProjectConfig: any, function initArkGuardConfig( obfuscationCacheDir: string | undefined, - logger: any, + printObfLogger: Function, mergedObConfig: MergedConfig, isHarCompiled: boolean, ): ArkObfuscator { @@ -116,25 +117,25 @@ function initArkGuardConfig( const arkObfuscator: ArkObfuscator = new ArkObfuscator(); arkObfuscator.init(arkguardConfig); if (mergedObConfig.options.applyNameCache && mergedObConfig.options.applyNameCache.length > 0) { - readNameCache(mergedObConfig.options.applyNameCache, logger); + readNameCache(mergedObConfig.options.applyNameCache, printObfLogger); } else { if (obfuscationCacheDir) { const defaultNameCachePath: string = path.join(obfuscationCacheDir, 'nameCache.json'); if (fs.existsSync(defaultNameCachePath)) { - readNameCache(defaultNameCachePath, logger); + readNameCache(defaultNameCachePath, printObfLogger); } } } if (mergedObConfig.options.printKeptNames && obfuscationCacheDir) { const defaultUnobfuscationPath: string = path.join(obfuscationCacheDir, 'keptNames.json'); if (fs.existsSync(defaultUnobfuscationPath)) { - readUnobfuscationContent(defaultUnobfuscationPath, logger); + readUnobfuscationContent(defaultUnobfuscationPath, printObfLogger); } } return arkObfuscator; } -function readUnobfuscationContent(defaultUnobfuscationPath: string, logger: any): void { +function readUnobfuscationContent(defaultUnobfuscationPath: string, printObfLogger: Function): void { try { const unobfuscationContent = fs.readFileSync(defaultUnobfuscationPath, 'utf-8'); const unobfuscationObj: { @@ -153,6 +154,14 @@ function readUnobfuscationContent(defaultUnobfuscationPath: string, logger: any) historyAllUnobfuscatedNamesMap.set(key, rest[key]); }); } catch (err) { - logger.error(`Failed to open ${defaultUnobfuscationPath}. Error message: ${err}`); + const errorInfo: string = `Failed to open ${defaultUnobfuscationPath}. Error message: ${err}`; + const errorCodeInfo: HvigorErrorInfo = { + code: '10804003', + description: 'ArkTS compiler Error', + cause: `Failed to open ${defaultUnobfuscationPath}. Error message: ${err}`, + position: defaultUnobfuscationPath, + solutions: [`Please check ${defaultUnobfuscationPath} as error message suggested.`], + }; + printObfLogger(errorInfo, errorCodeInfo, 'error'); } } diff --git a/arkguard/test/ut/initialization/ConfigResolver-hsp.spec.ts b/arkguard/test/ut/initialization/ConfigResolver-hsp.spec.ts index 7b85c2876638c0fb0c6a34e379c0760cfc6f6c82..93c20dfafab78c0178e60b64d346ef95e0df8c4f 100644 --- a/arkguard/test/ut/initialization/ConfigResolver-hsp.spec.ts +++ b/arkguard/test/ut/initialization/ConfigResolver-hsp.spec.ts @@ -18,12 +18,27 @@ import { SourceObConfig, } from '../../../src/initialization/ConfigResolver'; +import { HvigorErrorInfo, PropCollections, renameFileNameModule } from '../../../src/ArkObfuscator'; + import { describe, it } from 'mocha'; import { expect } from 'chai'; import path from 'path'; import fs from 'fs'; import exp from 'constants'; +function printObfLogger(errorInfo: string, errorCodeInfo: HvigorErrorInfo | string, level: string): void { + switch (level) { + case 'warn': + console.warn(errorInfo); + break; + case 'error': + console.error(errorInfo); + break; + default: + break; + } +} + describe('hsp support consumerFiles', () => { describe('hsp config resolver',() => { let hapConfig: SourceObConfig; @@ -242,7 +257,7 @@ describe('hsp support consumerFiles', () => { it('should include only HSP consumerFiles rules in HSP obfuscation.txt', function () { localHspConfig.dependencies.libraries.push(localHarConfig.selfConfig); localHspConfig.dependencies.hars.push(remoteHarObfFile); - const hspResolver = new ObConfigResolver({ obfuscationOptions: localHspConfig, compileHar: false, compileShared: true }, console); + const hspResolver = new ObConfigResolver({ obfuscationOptions: localHspConfig, compileHar: false, compileShared: true }, printObfLogger); hspResolver.resolveObfuscationConfigs(); const hspObfuscationContent = fs.readFileSync(localHspConfig.exportRulePath, 'utf-8'); @@ -272,7 +287,7 @@ describe('hsp support consumerFiles', () => { it('should merge HAR and HSP consumer rules for HAP when HAP depends on localHsp and localHsp depends on localHar', function () { hapConfig.dependencies.hspLibraries?.push(localHspConfig.selfConfig); - const configResolver = new ObConfigResolver({ obfuscationOptions: hapConfig, compileHar: false, compileShared: false }, console); + const configResolver = new ObConfigResolver({ obfuscationOptions: hapConfig, compileHar: false, compileShared: false }, printObfLogger); const finalConfig = configResolver.resolveObfuscationConfigs(); expect(finalConfig.options.enableToplevelObfuscation).to.be.false; expect(finalConfig.options.enableExportObfuscation).to.be.true; @@ -317,7 +332,7 @@ describe('hsp support consumerFiles', () => { it('should merge both HSP and HAR consumer rules in HAR obfuscation.txt', function () { localHarConfig.dependencies.hspLibraries?.push(localHspConfig.selfConfig); - const localHarResolver = new ObConfigResolver({ obfuscationOptions: localHarConfig, compileHar: true, compileShared: false }, console); + const localHarResolver = new ObConfigResolver({ obfuscationOptions: localHarConfig, compileHar: true, compileShared: false }, printObfLogger); localHarResolver.resolveObfuscationConfigs(); const localHarObfuscationContent = fs.readFileSync(localHarConfig.exportRulePath, 'utf-8'); @@ -346,7 +361,7 @@ describe('hsp support consumerFiles', () => { it('should merge HAR consumer rules for HAP when HAP depends on localHar and localHar depends on localHsp', function () { hapConfig.dependencies.libraries.push(localHarConfig.selfConfig); hapConfig.dependencies.hspLibraries?.push(localHspConfig.selfConfig); - const configResolver = new ObConfigResolver({ obfuscationOptions: hapConfig, compileHar: false, compileShared: false }, console); + const configResolver = new ObConfigResolver({ obfuscationOptions: hapConfig, compileHar: false, compileShared: false }, printObfLogger); const finalConfig = configResolver.resolveObfuscationConfigs(); expect(finalConfig.options.enableToplevelObfuscation).to.be.false; @@ -395,7 +410,7 @@ describe('hsp support consumerFiles', () => { it('should merge both HSP obfuscation.txt and HAR consumer rules in HAR obfuscation.txt', function () { localHarConfig.dependencies.hsps?.push(remoteHspObfFile); - const localHarResolver = new ObConfigResolver({ obfuscationOptions: localHarConfig, compileHar: true, compileShared: false }, console); + const localHarResolver = new ObConfigResolver({ obfuscationOptions: localHarConfig, compileHar: true, compileShared: false }, printObfLogger); localHarResolver.resolveObfuscationConfigs(); const localHarObfuscationContent = fs.readFileSync(localHarConfig.exportRulePath, 'utf-8'); @@ -424,7 +439,7 @@ describe('hsp support consumerFiles', () => { it('should merge HAR consumer rules for HAP when HAP depends on localHar and localHar depends on remoteHsp', function () { hapConfig.dependencies.libraries.push(localHarConfig.selfConfig); hapConfig.dependencies.hsps?.push(remoteHspObfFile); - const configResolver = new ObConfigResolver({ obfuscationOptions: hapConfig, compileHar: false, compileShared: false }, console); + const configResolver = new ObConfigResolver({ obfuscationOptions: hapConfig, compileHar: false, compileShared: false }, printObfLogger); const finalConfig = configResolver.resolveObfuscationConfigs(); expect(finalConfig.options.removeLog).to.be.false; @@ -473,7 +488,7 @@ describe('hsp support consumerFiles', () => { it('should retain HAR consumer rules for HAP when HAP depends on remoteHar and remoteHar depends on localHsp', function () { hapConfig.dependencies.hars.push(remoteHarDependsLocalHspObfFile); - const configResolver = new ObConfigResolver({ obfuscationOptions: hapConfig, compileHar: false, compileShared: false }, console); + const configResolver = new ObConfigResolver({ obfuscationOptions: hapConfig, compileHar: false, compileShared: false }, printObfLogger); const finalConfig = configResolver.resolveObfuscationConfigs(); expect(finalConfig.options.compact).to.be.false; @@ -522,7 +537,7 @@ describe('hsp support consumerFiles', () => { it('should retain HAR consumer rules for HAP when HAP depends on remoteHar and remoteHar depends on remoteHsp', function () { hapConfig.dependencies.hars.push(remoteHarDependsRemoteHspObfFile); - const configResolver = new ObConfigResolver({ obfuscationOptions: hapConfig, compileHar: false, compileShared: false }, console); + const configResolver = new ObConfigResolver({ obfuscationOptions: hapConfig, compileHar: false, compileShared: false }, printObfLogger); const finalConfig = configResolver.resolveObfuscationConfigs(); expect(finalConfig.options.compact).to.be.false; @@ -572,7 +587,7 @@ describe('hsp support consumerFiles', () => { it('should contain only MainHSP consumer rules in MainHSP obfuscation.txt', function () { localMainHspConfig.dependencies.hspLibraries?.push(localHspConfig.selfConfig); localMainHspConfig.dependencies.hsps?.push(remoteHspObfFile); - const localMainHspResolver = new ObConfigResolver({ obfuscationOptions: localMainHspConfig, compileHar: false, compileShared: true }, console); + const localMainHspResolver = new ObConfigResolver({ obfuscationOptions: localMainHspConfig, compileHar: false, compileShared: true }, printObfLogger); localMainHspResolver.resolveObfuscationConfigs(); const localMainHspObfuscationContent = fs.readFileSync(localMainHspConfig.exportRulePath, 'utf-8'); @@ -601,7 +616,7 @@ describe('hsp support consumerFiles', () => { it('should only retain MainHSP consumer rules when HAP depends on localMainHsp and localMainHsp depends on localHsp and remoteHsp', function () { hapConfig.dependencies.hspLibraries?.push(localMainHspConfig.selfConfig); - const hapResolver = new ObConfigResolver({ obfuscationOptions: hapConfig, compileHar: false, compileShared: false }, console); + const hapResolver = new ObConfigResolver({ obfuscationOptions: hapConfig, compileHar: false, compileShared: false }, printObfLogger); const finalConfig = hapResolver.resolveObfuscationConfigs(); expect(finalConfig.options.enableFileNameObfuscation).to.be.false; @@ -655,7 +670,7 @@ describe('hsp support consumerFiles', () => { it('should only retain MainHSP consumer rules for HAP when HAP depends on RemoteMainHsp and RemoteMainHsp depends on localHsp and remoteHsp', function () { hapConfig.dependencies.hsps?.push(remoteMainHspObfFile); - const hapResolver = new ObConfigResolver({ obfuscationOptions: hapConfig, compileHar: false, compileShared: false }, console); + const hapResolver = new ObConfigResolver({ obfuscationOptions: hapConfig, compileHar: false, compileShared: false }, printObfLogger); const finalConfig = hapResolver.resolveObfuscationConfigs(); expect(finalConfig.options.enableStringPropertyObfuscation).to.be.false; @@ -712,7 +727,7 @@ describe('hsp support consumerFiles', () => { hapConfig.dependencies.hars.push(remoteHarObfFile); hapConfig.dependencies.hspLibraries?.push(localHspConfig.selfConfig); hapConfig.dependencies.hsps?.push(remoteHspObfFile); - const hapResolver = new ObConfigResolver({ obfuscationOptions: hapConfig, compileHar: false, compileShared: false }, console); + const hapResolver = new ObConfigResolver({ obfuscationOptions: hapConfig, compileHar: false, compileShared: false }, printObfLogger); const finalConfig = hapResolver.resolveObfuscationConfigs(); expect(finalConfig.options.enableExportObfuscation).to.be.true; @@ -764,7 +779,7 @@ describe('hsp support consumerFiles', () => { libTestHapConfig.dependencies.hsps?.push(remoteHspObfFile); const hapResolver = new ObConfigResolver( { obfuscationOptions: libTestHapConfig, compileHar: false, compileShared: false }, - console, + printObfLogger, ); const finalConfig = hapResolver.resolveObfuscationConfigs(); diff --git a/arkguard/test/ut/initialization/ConfigResolver.spec.ts b/arkguard/test/ut/initialization/ConfigResolver.spec.ts index a250257ec4648270813176098dd760ced46c7e35..4f053ffdddc06ffb4be28b0f11a52265ab5d3a4f 100644 --- a/arkguard/test/ut/initialization/ConfigResolver.spec.ts +++ b/arkguard/test/ut/initialization/ConfigResolver.spec.ts @@ -35,7 +35,7 @@ import { SourceObConfig, Obfuscation } from '../../../src/initialization/ConfigResolver'; -import { PropCollections, renameFileNameModule } from '../../../src/ArkObfuscator'; +import { HvigorErrorInfo, PropCollections, renameFileNameModule } from '../../../src/ArkObfuscator'; import { nameCacheMap } from '../../../src/initialization/CommonObject'; import path from 'path'; import fs from 'fs'; @@ -48,9 +48,36 @@ const projectConfig = { obfuscationOptions: { option1: 'value1' }, compileHar: true }; + +function printObfLogger(errorInfo: string, errorCodeInfo: HvigorErrorInfo | string, level: string): void { + switch (level) { + case 'warn': + console.warn(errorInfo); + break; + case 'error': + console.error(errorInfo); + break; + default: + break; + } +} + +function printObfHvigorLogger(errorInfo: string, errorCodeInfo: HvigorErrorInfo | string, level: string): void { + switch (level) { + case 'warn': + console.warn(errorCodeInfo); + break; + case 'error': + console.error(errorCodeInfo); + break; + default: + break; + } +} + const logger = console; const isTerser = false; -let newObConfigResolver = new ObConfigResolver(projectConfig, logger, isTerser); +let newObConfigResolver = new ObConfigResolver(projectConfig, printObfLogger, isTerser); describe('test for ConfigResolve', function() { describe('ObOptions', () => { @@ -178,13 +205,11 @@ describe('test for ConfigResolve', function() { obfuscationOptions: { option1: 'value1' }, compileHar: true }; - const logger = console; const isTerser = false; - const myInstance = new ObConfigResolver(projectConfig, logger, isTerser); + const myInstance = new ObConfigResolver(projectConfig, printObfLogger, isTerser); expect(myInstance).to.be.an('object'); expect(myInstance.sourceObConfig).to.deep.equal({ option1: 'value1' }); - expect(myInstance.logger).to.equal(console); expect(myInstance.isHarCompiled).to.be.true; expect(myInstance.isTerser).to.be.false; }); @@ -194,12 +219,10 @@ describe('test for ConfigResolve', function() { obfuscationOptions: { option1: 'value1' }, compileHar: true }; - const logger = console; - const myInstance = new ObConfigResolver(projectConfig, logger, true); + const myInstance = new ObConfigResolver(projectConfig, printObfLogger, true); expect(myInstance).to.be.an('object'); expect(myInstance.sourceObConfig).to.deep.equal({ option1: 'value1' }); - expect(myInstance.logger).to.equal(console); expect(myInstance.isHarCompiled).to.be.true; expect(myInstance.isTerser).to.be.true; }); @@ -212,7 +235,7 @@ describe('test for ConfigResolve', function() { }; const logger = console; const isTerser = false; - let newObConfigResolver = new ObConfigResolver(projectConfig, logger, isTerser); + let newObConfigResolver = new ObConfigResolver(projectConfig, printObfLogger, isTerser); let testClass: ObConfigResolver & { performancePrinter?: any; }; @@ -423,13 +446,11 @@ describe('test for ConfigResolve', function() { }, compileHar: true }; - const logger = console; const isTerser = false; - const resolver = new ObConfigResolver(projectConfig, logger, isTerser); + const resolver = new ObConfigResolver(projectConfig, printObfLogger, isTerser); expect(resolver).to.be.an('object'); expect(resolver.sourceObConfig).to.deep.equal(projectConfig.obfuscationOptions); - expect(resolver.logger).to.equal(logger); expect(resolver.isHarCompiled).to.equal(projectConfig.compileHar); expect(resolver.isTerser).to.equal(isTerser); }); @@ -445,13 +466,11 @@ describe('test for ConfigResolve', function() { }, compileHar: true }; - const logger = console; const isTerser = false; - const resolver = new ObConfigResolver(projectConfig, logger, isTerser); + const resolver = new ObConfigResolver(projectConfig, printObfLogger, isTerser); expect(resolver).to.be.an('object'); expect(resolver.sourceObConfig).to.deep.equal(projectConfig.obfuscationOptions); - expect(resolver.logger).to.equal(logger); expect(resolver.isHarCompiled).to.equal(projectConfig.compileHar); expect(resolver.isTerser).to.equal(isTerser); }); @@ -467,16 +486,14 @@ describe('test for ConfigResolve', function() { }, compileHar: true }; - const logger = console; const isTerser = false; - const resolver = new ObConfigResolver(projectConfig, logger, isTerser); + const resolver = new ObConfigResolver(projectConfig, printObfLogger, isTerser); const selfConfigs = new MergedConfig(); resolver.getSelfConfigsForTest(selfConfigs); expect(resolver).to.be.an('object'); expect(resolver.sourceObConfig).to.deep.equal(projectConfig.obfuscationOptions); - expect(resolver.logger).to.equal(logger); expect(resolver.isHarCompiled).to.equal(projectConfig.compileHar); expect(resolver.isTerser).to.equal(isTerser); }); @@ -493,13 +510,12 @@ describe('test for ConfigResolve', function() { }, compileHar: true }; - const logger = console; let sandbox; let instance; beforeEach(() => { sandbox = sinon.createSandbox(); - instance = new ObConfigResolver(projectConfig, logger, true); + instance = new ObConfigResolver(projectConfig, printObfLogger, true); instance.logger = { error: sandbox.stub() }; }); @@ -524,12 +540,36 @@ describe('test for ConfigResolve', function() { it('should log error and throw when failed to open file', () => { const path = './test/testData/obfuscation/filename_obf/non-existent-file.json'; const configs = new MergedConfig(); - const errorMessage = `Failed to open ${path}. Error message: ENOENT: no such file or directory, open '${path}'`; - - sandbox.stub(fs, 'readFileSync').throws(new Error(errorMessage)); + const stub = sinon.stub(console, 'error'); + const errorMessage = `Failed to open ${path}. Error message: Error: ENOENT: no such file or directory, open ${path}`; + sandbox.stub(fs, 'readFileSync').throws(new Error(`ENOENT: no such file or directory, open ${path}`)); + try { + instance.getConfigByPath(path, configs); + } catch (err) { + } + expect(stub.calledWith(errorMessage)).to.be.true; + stub.restore(); + }); - expect(() => instance.getConfigByPath(path, configs)).to.throw(Error, errorMessage); - expect(instance.logger.error.calledWith(errorMessage)).to.be.false; + it('should log error and throw when failed to open file with hvigor errorCode', () => { + const path = './test/testData/obfuscation/filename_obf/non-existent-file.json'; + const configs = new MergedConfig(); + const stub = sinon.stub(console, 'error'); + const errorMessage = { + code: '10804001', + description: 'ArkTS compiler Error', + cause: `Failed to open obfuscation config file from ${path}. Error message: Error: ENOENT: no such file or directory, open ${path}`, + position: path, + solutions: [`Please check whether ${path} exists.`], + }; + instance = new ObConfigResolver(projectConfig, printObfHvigorLogger, true); + sandbox.stub(fs, 'readFileSync').throws(new Error(`ENOENT: no such file or directory, open ${path}`)); + try { + instance.getConfigByPath(path, configs); + } catch (err) { + } + expect(stub.calledWith(errorMessage)).to.be.true; + stub.restore(); }); }); @@ -1160,7 +1200,7 @@ describe('test for ConfigResolve', function() { }; const logger = console; const isTerser = false; - let newObConfigResolver = new ObConfigResolver(projectConfig, logger, isTerser); + let newObConfigResolver = new ObConfigResolver(projectConfig, printObfLogger, isTerser); const res: MergedConfig = newObConfigResolver.getMergedConfigsForTest(config1, config2); expect(res.options.enablePropertyObfuscation).to.be.true; @@ -1195,7 +1235,7 @@ describe('test for ConfigResolve', function() { }; const logger = console; const isTerser = false; - let newObConfigResolver = new ObConfigResolver(projectConfig, logger, isTerser); + let newObConfigResolver = new ObConfigResolver(projectConfig, printObfLogger, isTerser); const res: MergedConfig = newObConfigResolver.getMergedConfigsForTest(config1, config2); expect(res.options.enablePropertyObfuscation).to.be.false; @@ -1232,7 +1272,7 @@ describe('test for ConfigResolve', function() { }; const logger = console; const isTerser = false; - let newObConfigResolver = new ObConfigResolver(projectConfig, logger, isTerser); + let newObConfigResolver = new ObConfigResolver(projectConfig, printObfLogger, isTerser); const sourceObConfig: SourceObConfig = { selfConfig: {} as Obfuscation, sdkApis: [], @@ -1283,7 +1323,7 @@ describe('test for ConfigResolve', function() { }; const logger = console; const isTerser = false; - let newObConfigResolver = new ObConfigResolver(projectConfig, logger, isTerser); + let newObConfigResolver = new ObConfigResolver(projectConfig, printObfLogger, isTerser); const sourceObConfig: SourceObConfig = { selfConfig: {} as Obfuscation, sdkApis: [], @@ -1375,9 +1415,6 @@ describe('test for ConfigResolve', function() { let testData; let fsWriteFileSyncStub; let fsUnlinkSyncStub; - let logger = { - error: (message: string) => console.error(message), - }; let PropCollections; let renameFileNameModule; @@ -1407,7 +1444,7 @@ describe('test for ConfigResolve', function() { }); it('should read and parse the name cache file correctly', () => { - readNameCache(tempFilePath, logger); + readNameCache(tempFilePath, printObfLogger); expect(nameCacheMap.get('extraKey')).to.equal(''); }); @@ -1420,7 +1457,7 @@ describe('test for ConfigResolve', function() { beforeEach(() => { fsReadFileSyncStub = sinon.stub(fs, 'readFileSync').returns('{"compileSdkVersion":"1.0","PropertyCache":{},"FileNameCache":{}}'); - logger = { error: sinon.spy() }; + logger = { error: sinon.spy(), printError: (msg)=>{}}; }); afterEach(() => { @@ -1428,7 +1465,7 @@ describe('test for ConfigResolve', function() { }); it('should read the name cache file and parse its content', () => { - readNameCache(testPath, logger); + readNameCache(testPath, printObfLogger); expect(PropCollections.historyMangledTable).to.deep.equal(new Map()); expect(renameFileNameModule.historyFileNameMangledTable).to.deep.equal(new Map()); expect(nameCacheMap.get('compileSdkVersion')).to.be.undefined; @@ -1441,11 +1478,32 @@ describe('test for ConfigResolve', function() { }; const nonExistentFilePath = './test/ut/initialization/nonExistentFile.json'; - readNameCache(nonExistentFilePath, mockLogger); - fsReadFileSyncStub.throws(new Error('Test error')); - readNameCache(testPath, logger); + try { + readNameCache(nonExistentFilePath, printObfLogger); + } catch (err) { + } expect(logger.error.calledWith(`Failed to open ${nonExistentFilePath}. Error message: Test error`)).to.be.false; }); + + it('should handle errors when reading the file with hvigor errorCode', () => { + const mockLogger = { + error: (message: string) => console.error(message), + }; + + const nonExistentFilePath = './test/ut/initialization/nonExistentFile.json'; + try { + readNameCache(nonExistentFilePath, printObfHvigorLogger); + } catch (err) { + } + const errorMessage = { + code: '10804002', + description: 'ArkTS compiler Error', + cause: `Failed to open namecache file from ${nonExistentFilePath}, Error message: Test error`, + position: nonExistentFilePath, + solutions: [`Please check ${nonExistentFilePath} as error message suggested.`], + }; + expect(logger.error.calledWith(errorMessage)).to.be.false; + }); }); describe('handleUniversalPathInObf', () => {