fix test and logging

This commit is contained in:
Florian Dold 2022-09-13 15:28:34 +02:00
parent 48540f6264
commit 676ae5102b
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
5 changed files with 44 additions and 45 deletions

View File

@ -226,6 +226,9 @@ async function withWallet<T>(
const wallet = await getDefaultNodeWallet({
persistentStoragePath: dbPath,
httpLib: myHttpLib,
notifyHandler: (n) => {
logger.info(`wallet notification: ${j2s(n)}`);
},
});
if (checkEnvFlag("TALER_WALLET_BATCH_WITHDRAWAL")) {

View File

@ -189,17 +189,10 @@ export async function runExchangeManagementTest(
});
});
// Updating the exchange from the base URL is technically a pending operation
// and it will be retried later.
t.assertTrue(
err1.hasErrorCode(TalerErrorCode.WALLET_PENDING_OPERATION_FAILED),
);
// Response is malformed, since it didn't even contain a version code
// in a format the wallet can understand.
t.assertTrue(
err1.errorDetail.innerError.code ===
TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE,
err1.errorDetail.code === TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE,
);
exchangesList = await wallet.client.call(
@ -238,12 +231,9 @@ export async function runExchangeManagementTest(
});
t.assertTrue(
err2.hasErrorCode(TalerErrorCode.WALLET_PENDING_OPERATION_FAILED),
);
t.assertTrue(
err2.errorDetail.innerError.code ===
err2.hasErrorCode(
TalerErrorCode.WALLET_EXCHANGE_PROTOCOL_VERSION_INCOMPATIBLE,
),
);
exchangesList = await wallet.client.call(

View File

@ -102,14 +102,7 @@ export async function runPaymentClaimTest(t: GlobalTestState) {
});
});
t.assertTrue(
err.hasErrorCode(TalerErrorCode.WALLET_PENDING_OPERATION_FAILED),
);
t.assertTrue(
err.errorDetail.innerError.code ===
TalerErrorCode.WALLET_ORDER_ALREADY_CLAIMED,
);
t.assertTrue(err.hasErrorCode(TalerErrorCode.WALLET_ORDER_ALREADY_CLAIMED));
await t.shutdown();
}

View File

@ -102,7 +102,7 @@ export function summarizeTalerErrorDetail(ed: TalerErrorDetail): string {
export class TalerError<T = any> extends Error {
errorDetail: TalerErrorDetail & T;
private constructor(d: TalerErrorDetail & T) {
super();
super(d.hint ?? `Error (code ${d.code})`);
this.errorDetail = d;
Object.setPrototypeOf(this, TalerError.prototype);
}

View File

@ -289,8 +289,9 @@ async function callOperationHandler(
forceNow,
});
case PendingTaskType.Withdraw:
await processWithdrawalGroup(ws, pending.withdrawalGroupId, { forceNow });
break;
return await processWithdrawalGroup(ws, pending.withdrawalGroupId, {
forceNow,
});
case PendingTaskType.ProposalDownload:
return await processDownloadProposal(ws, pending.proposalId, {
forceNow,
@ -319,7 +320,7 @@ async function callOperationHandler(
default:
return assertUnreachable(pending);
}
throw Error("not reached");
throw Error(`not reached ${pending.type}`);
}
export async function storeOperationError(
@ -330,12 +331,17 @@ export async function storeOperationError(
await ws.db
.mktx((x) => [x.operationRetries])
.runReadWrite(async (tx) => {
const retryRecord = await tx.operationRetries.get(pendingTaskId);
let retryRecord = await tx.operationRetries.get(pendingTaskId);
if (!retryRecord) {
return;
}
retryRecord = {
id: pendingTaskId,
lastError: e,
retryInfo: RetryInfo.reset(),
};
} else {
retryRecord.lastError = e;
retryRecord.retryInfo = RetryInfo.increment(retryRecord.retryInfo);
}
await tx.operationRetries.put(retryRecord);
});
}
@ -358,12 +364,16 @@ export async function storeOperationPending(
await ws.db
.mktx((x) => [x.operationRetries])
.runReadWrite(async (tx) => {
const retryRecord = await tx.operationRetries.get(pendingTaskId);
let retryRecord = await tx.operationRetries.get(pendingTaskId);
if (!retryRecord) {
return;
}
retryRecord = {
id: pendingTaskId,
retryInfo: RetryInfo.reset(),
};
} else {
delete retryRecord.lastError;
retryRecord.retryInfo = RetryInfo.increment(retryRecord.retryInfo);
}
await tx.operationRetries.put(retryRecord);
});
}
@ -392,24 +402,18 @@ async function processOnePendingOperation(
case OperationAttemptResultType.Longpoll:
break;
}
} catch (e: any) {
if (
e instanceof TalerError &&
e.hasErrorCode(TalerErrorCode.WALLET_PENDING_OPERATION_FAILED)
) {
} catch (e) {
if (e instanceof TalerError) {
logger.warn("operation processed resulted in error");
logger.warn(`error was: ${j2s(e.errorDetail)}`);
maybeError = e.errorDetail;
} else {
return await storeOperationError(ws, pending.id, maybeError!);
} else if (e instanceof Error) {
// This is a bug, as we expect pending operations to always
// do their own error handling and only throw WALLET_PENDING_OPERATION_FAILED
// or return something.
logger.error("Uncaught exception", e);
ws.notify({
type: NotificationType.InternalError,
message: "uncaught exception",
exception: e,
});
logger.error(`Uncaught exception: ${e.message}`);
logger.error(`Stack: ${e.stack}`);
maybeError = makeErrorDetail(
TalerErrorCode.WALLET_UNEXPECTED_EXCEPTION,
{
@ -417,6 +421,15 @@ async function processOnePendingOperation(
},
`unexpected exception (message: ${e.message})`,
);
return await storeOperationError(ws, pending.id, maybeError);
} else {
logger.error("Uncaught exception, value is not even an error.");
maybeError = makeErrorDetail(
TalerErrorCode.WALLET_UNEXPECTED_EXCEPTION,
{},
`unexpected exception (not even an error)`,
);
return await storeOperationError(ws, pending.id, maybeError);
}
}
}