Initial commit: code as received (Create/Anything export)
Insole-production time tracker exported from the Create/Anything AI platform. Baseline snapshot before any reverse-engineering or cleanup. - apps/mobile: Expo Router app (iOS/Android/web), the only workspace - publisher/: standalone OpenNext/AWS deploy tooling for the web side - Backend (/api/tasks, /api/logs + DB) lives remotely, not in this repo
This commit is contained in:
79
apps/mobile/__create/handle-resolve-request-error.js
Normal file
79
apps/mobile/__create/handle-resolve-request-error.js
Normal file
@@ -0,0 +1,79 @@
|
||||
const crypto = require('node:crypto');
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
const { reportErrorToRemote } = require('./report-error-to-remote');
|
||||
|
||||
const VIRTUAL_ROOT = path.join(__dirname, '../.metro-virtual');
|
||||
const VIRTUAL_ROOT_UNRESOLVED = path.join(VIRTUAL_ROOT, 'unresolved');
|
||||
|
||||
const handleResolveRequestError = ({
|
||||
error,
|
||||
context,
|
||||
moduleName,
|
||||
platform,
|
||||
}) => {
|
||||
const errorMessage = `Unable to resolve module '${moduleName}' from '${context.originModulePath}'`;
|
||||
const syntheticError = new Error(errorMessage);
|
||||
syntheticError.stack = error.stack;
|
||||
reportErrorToRemote({ error: syntheticError }).catch((_reportError) => {
|
||||
// no-op
|
||||
});
|
||||
if (process.env.NODE_ENV === 'production') throw error;
|
||||
if (platform === 'android') throw error;
|
||||
if (!__DEV__ && process.env.EXPO_PUBLIC_CREATE_ENV !== 'DEVELOPMENT')
|
||||
throw error;
|
||||
|
||||
// Build a deterministic virtual file path for this failed request
|
||||
const key = `${moduleName}|${context.originModulePath}|${platform}`;
|
||||
const hash = crypto
|
||||
.createHash('sha256')
|
||||
.update(key)
|
||||
.digest('hex')
|
||||
.slice(0, 16);
|
||||
|
||||
fs.mkdirSync(VIRTUAL_ROOT_UNRESOLVED, { recursive: true });
|
||||
const vfile = path.join(VIRTUAL_ROOT_UNRESOLVED, `throw-${hash}.js`);
|
||||
|
||||
// Serialize a safe payload for the client
|
||||
const payload = {
|
||||
moduleName,
|
||||
from: context.originModulePath,
|
||||
platform,
|
||||
originalMessage: String(
|
||||
error?.message ? error.message : 'Unknown resolve error'
|
||||
),
|
||||
};
|
||||
|
||||
const code = [
|
||||
'// Auto generated by custom Metro resolver',
|
||||
'(function(){',
|
||||
` var info = ${JSON.stringify(payload)};`,
|
||||
" var msg = 'Unable to resolve \"' + info.moduleName + '\" from \"' + info.from + '\"';",
|
||||
" msg += '\\n\\n' + info.originalMessage;",
|
||||
' var e = new Error(msg);',
|
||||
" e.name = 'ModuleResolveError';",
|
||||
" e.code = 'MODULE_RESOLVE_FAILED';",
|
||||
' throw e;',
|
||||
'})();',
|
||||
'export {};', // keep ESM shape harmlessly
|
||||
'',
|
||||
].join('\n');
|
||||
|
||||
// Only write if content changed — avoids bumping mtime and triggering Metro rebuild loop
|
||||
const existingContent = fs.existsSync(vfile) ? fs.readFileSync(vfile, 'utf8') : null;
|
||||
if (existingContent !== code) {
|
||||
fs.writeFileSync(vfile, code, 'utf8');
|
||||
}
|
||||
|
||||
// Tell Metro to load our thrower as a real source file
|
||||
return {
|
||||
filePath: vfile,
|
||||
type: 'sourceFile',
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
handleResolveRequestError,
|
||||
VIRTUAL_ROOT,
|
||||
VIRTUAL_ROOT_UNRESOLVED,
|
||||
};
|
||||
Reference in New Issue
Block a user