import { relogin } from './client' import log from './log' /** * Run a server call through the same error handling the old `emissary.serverCall` * did, on top of `@tlecommunity/client`'s non-throwing `{ result, error }` model: * * - success -> resolves to the bare `result` (envelope stripped) * - `Session expired.` (code 1006) -> re-login, then run the call once more * - anything else -> throws `error.message` as a **string** * * The click-limit ("Slow down" / 1010) case is handled transparently by the * `onResponse` handler in `client.js` and never reaches here. * * Throwing a string (never an `Error`) is deliberate: `util.handlePromiseError` * logs strings and rethrows everything else, and `eachPlanet` / `push-buildings-up` * rely on per-item failures being swallowed. * * Because a settled promise can't be re-issued, pass a **thunk** to get the * session-expiry retry: `call(() => lacuna.body.getStatus({ body_id }))`. A bare * promise still works for the happy path. * * @param {Function|Promise} work - a `() => ServerResponse` thunk (preferred) or a promise * @return {Promise<*>} the unwrapped result */ export default async function call(work) { const run = () => (typeof work === 'function' ? work() : work) let { result, error } = await run() if (!error) { return result } if (error.code === 1006 || error.message === 'Session expired.') { log.newline() log.warn('Session expired - logging in again') await relogin() log.info('Trying again') log.newline() if (typeof work !== 'function') { throw error.message || `Server error ${error.code}` } ;({ result, error } = await run()) if (!error) { return result } } throw error.message || `Server error ${error.code}` }