From af9ec577d08d75b12947aee959186b51b16af9fb Mon Sep 17 00:00:00 2001 From: Jacek Sieka Date: Thu, 29 Sep 2022 22:55:18 +0200 Subject: [PATCH] nicer error message for failed backfill (#4188) * nicer error message for failed backfill Many checkpoint sources don't support block download * RestGenericError -> RestErrorMessage ...and other assorted fixes to bring rest types closer to spec * fix tests --- AllTests-mainnet.md | 4 +- beacon_chain/deposits.nim | 2 +- beacon_chain/rpc/rest_beacon_api.nim | 16 +-- beacon_chain/rpc/rest_validator_api.nim | 10 +- .../eth2_apis/eth2_rest_serialization.nim | 40 +++---- .../spec/eth2_apis/rest_beacon_calls.nim | 10 +- beacon_chain/spec/eth2_apis/rest_common.nim | 2 +- .../spec/eth2_apis/rest_debug_calls.nim | 22 ++-- beacon_chain/spec/eth2_apis/rest_types.nim | 16 ++- beacon_chain/trusted_node_sync.nim | 50 ++++---- beacon_chain/validator_client/api.nim | 113 +++++++++--------- tests/test_serialization.nim | 47 ++++---- 12 files changed, 169 insertions(+), 163 deletions(-) diff --git a/AllTests-mainnet.md b/AllTests-mainnet.md index 2cf7d98df..68d79d950 100644 --- a/AllTests-mainnet.md +++ b/AllTests-mainnet.md @@ -369,8 +369,8 @@ OK: 3/3 Fail: 0/3 Skip: 0/3 OK: 1/1 Fail: 0/1 Skip: 0/1 ## Serialization/deserialization test suite ```diff -+ RestGenericError parser tests OK -+ RestGenericError writer tests OK ++ RestErrorMessage parser tests OK ++ RestErrorMessage writer tests OK ``` OK: 2/2 Fail: 0/2 Skip: 0/2 ## Slashing Interchange tests [Preset: mainnet] diff --git a/beacon_chain/deposits.nim b/beacon_chain/deposits.nim index e02c7a67d..56d3fb297 100644 --- a/beacon_chain/deposits.nim +++ b/beacon_chain/deposits.nim @@ -214,7 +214,7 @@ proc restValidatorExit(config: BeaconNodeConf) {.async.} = quit 0 else: let responseError = try: - Json.decode(response.data, RestGenericError) + Json.decode(response.data, RestErrorMessage) except CatchableError as err: fatal "Failed to decode invalid error server response on `submitPoolVoluntaryExit` request", err = err.msg diff --git a/beacon_chain/rpc/rest_beacon_api.nim b/beacon_chain/rpc/rest_beacon_api.nim index cb71e4082..56a39a220 100644 --- a/beacon_chain/rpc/rest_beacon_api.nim +++ b/beacon_chain/rpc/rest_beacon_api.nim @@ -969,20 +969,20 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) = res let failures = block: - var res: seq[RestAttestationsFailure] + var res: seq[RestIndexedErrorMessageItem] await allFutures(pending) for index, future in pending: if future.done(): let fres = future.read() if fres.isErr(): - let failure = RestAttestationsFailure(index: uint64(index), - message: $fres.error()) + let failure = RestIndexedErrorMessageItem(index: index, + message: $fres.error()) res.add(failure) elif future.failed() or future.cancelled(): # This is unexpected failure, so we log the error message. let exc = future.readError() - let failure = RestAttestationsFailure(index: uint64(index), - message: $exc.msg) + let failure = RestIndexedErrorMessageItem(index: index, + message: $exc.msg) res.add(failure) res @@ -1073,11 +1073,11 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) = let failures = block: - var res: seq[RestAttestationsFailure] + var res: seq[RestIndexedErrorMessageItem] for index, item in results: if item.isErr(): - res.add(RestAttestationsFailure(index: uint64(index), - message: $item.error())) + res.add(RestIndexedErrorMessageItem(index: index, + message: $item.error())) res if len(failures) > 0: return RestApiResponse.jsonErrorList(Http400, diff --git a/beacon_chain/rpc/rest_validator_api.nim b/beacon_chain/rpc/rest_validator_api.nim index c6a4183e5..40fa09df3 100644 --- a/beacon_chain/rpc/rest_validator_api.nim +++ b/beacon_chain/rpc/rest_validator_api.nim @@ -742,20 +742,20 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) = let failures = block: - var res: seq[RestAttestationsFailure] + var res: seq[RestIndexedErrorMessageItem] await allFutures(pending) for index, future in pending: if future.done(): let fres = future.read() if fres.isErr(): - let failure = RestAttestationsFailure(index: uint64(index), - message: $fres.error()) + let failure = RestIndexedErrorMessageItem(index: index, + message: $fres.error()) res.add(failure) elif future.failed() or future.cancelled(): # This is unexpected failure, so we log the error message. let exc = future.readError() - let failure = RestAttestationsFailure(index: uint64(index), - message: $exc.msg) + let failure = RestIndexedErrorMessageItem(index: index, + message: $exc.msg) res.add(failure) res diff --git a/beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim b/beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim index 257a2c4c4..00d9ad588 100644 --- a/beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim +++ b/beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim @@ -72,16 +72,6 @@ const type EmptyBody* = object - RestGenericError* = object - code*: uint64 - message*: string - stacktraces*: Option[seq[string]] - - RestDutyError* = object - code*: uint64 - message*: string - failures*: seq[RestFailureItem] - EncodeTypes* = AttesterSlashing | DeleteKeystoresBody | @@ -128,8 +118,8 @@ type ListFeeRecipientResponse | PrepareBeaconProposer | ProduceBlockResponseV2 | - RestDutyError | - RestGenericError | + RestIndexedErrorMessage | + RestErrorMessage | RestValidator | Web3SignerErrorResponse | Web3SignerKeysResponse | @@ -2220,12 +2210,12 @@ proc writeValue*(writer: var JsonWriter[RestJson], writer.writeField("is_optimistic", value.is_optimistic.get()) writer.endRecord() -## RestGenericError +## RestErrorMessage proc readValue*(reader: var JsonReader[RestJson], - value: var RestGenericError) {. + value: var RestErrorMessage) {. raises: [SerializationError, IOError, Defect].} = var - code: Opt[uint64] + code: Opt[int] message: Opt[string] stacktraces: Option[seq[string]] @@ -2234,30 +2224,34 @@ proc readValue*(reader: var JsonReader[RestJson], of "code": if code.isSome(): reader.raiseUnexpectedField("Multiple `code` fields found", - "RestGenericError") + "RestErrorMessage") let ires = try: let res = reader.readValue(int) if res < 0: reader.raiseUnexpectedValue("Invalid `code` field value") - Opt.some(uint64(res)) + Opt.some(res) except SerializationError: - Opt.none(uint64) + Opt.none(int) if ires.isNone(): - let sres = Base10.decode(uint64, reader.readValue(string)).valueOr: - reader.raiseUnexpectedValue("Invalid `code` field format") + let sres = + try: parseInt(reader.readValue(string)) + except ValueError: + reader.raiseUnexpectedValue("Invalid `code` field format") + if sres < 0: + reader.raiseUnexpectedValue("Invalid `code` field value") code = Opt.some(sres) else: code = ires of "message": if message.isSome(): reader.raiseUnexpectedField("Multiple `message` fields found", - "RestGenericError") + "RestErrorMessage") message = Opt.some(reader.readValue(string)) of "stacktraces": if stacktraces.isSome(): reader.raiseUnexpectedField("Multiple `stacktraces` fields found", - "RestGenericError") + "RestErrorMessage") stacktraces = some(reader.readValue(seq[string])) else: # We ignore all additional fields. @@ -2268,7 +2262,7 @@ proc readValue*(reader: var JsonReader[RestJson], if message.isNone(): reader.raiseUnexpectedValue("Missing or invalid `message` value") - value = RestGenericError( + value = RestErrorMessage( code: code.get(), message: message.get(), stacktraces: stacktraces ) diff --git a/beacon_chain/spec/eth2_apis/rest_beacon_calls.nim b/beacon_chain/spec/eth2_apis/rest_beacon_calls.nim index eadb36435..748b2a63c 100644 --- a/beacon_chain/spec/eth2_apis/rest_beacon_calls.nim +++ b/beacon_chain/spec/eth2_apis/rest_beacon_calls.nim @@ -157,16 +157,16 @@ proc getBlockV2*(client: RestClientRef, block_id: BlockIdent, of 404: none(ref ForkedSignedBeaconBlock) of 400, 500: - let error = decodeBytes(RestGenericError, resp.data, + let error = decodeBytes(RestErrorMessage, resp.data, resp.contentType).valueOr: let msg = "Incorrect response error format (" & $resp.status & ") [" & $error & "]" - raise newException(RestError, msg) + raise (ref RestResponseError)(msg: msg, status: resp.status) let msg = "Error response (" & $resp.status & ") [" & error.message & "]" - raise newException(RestError, msg) + raise (ref RestResponseError)( + msg: msg, status: error.code, message: error.message) else: - let msg = "Unknown response status error (" & $resp.status & ")" - raise newException(RestError, msg) + raiseRestResponseError(resp) proc getBlockRoot*(block_id: BlockIdent): RestResponse[GetBlockRootResponse] {. rest, endpoint: "/eth/v1/beacon/blocks/{block_id}/root", diff --git a/beacon_chain/spec/eth2_apis/rest_common.nim b/beacon_chain/spec/eth2_apis/rest_common.nim index 71493cdda..810b4abce 100644 --- a/beacon_chain/spec/eth2_apis/rest_common.nim +++ b/beacon_chain/spec/eth2_apis/rest_common.nim @@ -19,7 +19,7 @@ proc raiseGenericError*(resp: RestPlainResponse) {. noreturn, raises: [RestError, Defect].} = let error = block: - let res = decodeBytes(RestGenericError, resp.data, resp.contentType) + let res = decodeBytes(RestErrorMessage, resp.data, resp.contentType) if res.isErr(): let msg = "Incorrect response error format (" & $resp.status & ") [" & $res.error() & "]" diff --git a/beacon_chain/spec/eth2_apis/rest_debug_calls.nim b/beacon_chain/spec/eth2_apis/rest_debug_calls.nim index 3ced74c84..ffab8b5c9 100644 --- a/beacon_chain/spec/eth2_apis/rest_debug_calls.nim +++ b/beacon_chain/spec/eth2_apis/rest_debug_calls.nim @@ -37,7 +37,7 @@ proc getStateV2*(client: RestClientRef, state_id: StateIdent, await client.getStateV2Plain(state_id, restAcceptType = restAccept) else: await client.getStateV2Plain(state_id) - let data = + return case resp.status of 200: if resp.contentType.isNone() or @@ -64,17 +64,13 @@ proc getStateV2*(client: RestClientRef, state_id: StateIdent, of 404: nil of 400, 500: - let error = - block: - let res = decodeBytes(RestGenericError, resp.data, resp.contentType) - if res.isErr(): - let msg = "Incorrect response error format (" & $resp.status & - ") [" & $res.error() & "]" - raise newException(RestError, msg) - res.get() + let error = decodeBytes(RestErrorMessage, resp.data, + resp.contentType).valueOr: + let msg = "Incorrect response error format (" & $resp.status & + ") [" & $error & "]" + raise (ref RestResponseError)(msg: msg, status: resp.status) let msg = "Error response (" & $resp.status & ") [" & error.message & "]" - raise newException(RestError, msg) + raise (ref RestResponseError)( + msg: msg, status: error.code, message: error.message) else: - let msg = "Unknown response status error (" & $resp.status & ")" - raise newException(RestError, msg) - return data + raiseRestResponseError(resp) diff --git a/beacon_chain/spec/eth2_apis/rest_types.nim b/beacon_chain/spec/eth2_apis/rest_types.nim index a1645d790..2349eb7d9 100644 --- a/beacon_chain/spec/eth2_apis/rest_types.nim +++ b/beacon_chain/spec/eth2_apis/rest_types.nim @@ -167,12 +167,20 @@ type slot*: Slot validators*: seq[ValidatorIndex] - RestFailureItem* = object - index*: uint64 + RestErrorMessage* = object + ## https://github.com/ethereum/beacon-APIs/blob/v2.3.0/types/http.yaml#L86 + code*: int message*: string + stacktraces*: Option[seq[string]] - RestAttestationsFailure* = object - index*: uint64 + RestIndexedErrorMessage* = object + ## https://github.com/ethereum/beacon-APIs/blob/v2.3.0/types/http.yaml#L101 + code*: int + message*: string + failures*: seq[RestIndexedErrorMessageItem] + + RestIndexedErrorMessageItem* = object + index*: int message*: string RestValidator* = object diff --git a/beacon_chain/trusted_node_sync.nim b/beacon_chain/trusted_node_sync.nim index fc3d3c173..5ef109cfe 100644 --- a/beacon_chain/trusted_node_sync.nim +++ b/beacon_chain/trusted_node_sync.nim @@ -106,17 +106,21 @@ proc doTrustedNodeSync*( for i in 0..<3: try: return await client.getBlockV2(BlockIdent.init(slot), cfg) - except CatchableError as exc: + except RestResponseError as exc: lastError = exc + notice "Server does not support block downloads / backfilling", + msg = exc.msg + break + except CatchableError as exc: + # We'll assume this may be a connectivity error or something similar + lastError = exc + warn "Retrying download of block", slot, err = exc.msg client = RestClientRef.new(restUrl).valueOr: error "Cannot connect to server", url = restUrl, error = error quit 1 - error "Unable to download block - backfill incomplete, but will resume when you start the beacon node", - slot, error = lastError.msg, url = client.address - - quit 1 + raise lastError let localGenesisRoot = db.getGenesisBlock().valueOr: @@ -280,8 +284,8 @@ proc doTrustedNodeSync*( dbCache.update(blck) (checkpointSlot, checkpointBlock[].root) else: - notice "Skipping checkpoint download, database already exists", - head = shortLog(dbHead.get()) + notice "Skipping checkpoint download, database already exists (remove db directory to get a fresh snapshot)", + databaseDir, head = shortLog(dbHead.get()) (headSlot, dbHead.get()) # Coming this far, we've done what ChainDAGRef.preInit would normally do - @@ -383,23 +387,27 @@ proc doTrustedNodeSync*( # Download blocks backwards from the checkpoint slot, skipping the ones we # already have in the database. We'll do a few downloads in parallel which # risks having some redundant downloads going on, but speeds things up - for i in 0'u64..<(checkpointSlot.uint64 + gets.lenu64()): - if not isNil(gets[int(i mod gets.lenu64)]): - await processBlock( - gets[int(i mod gets.lenu64)], - checkpointSlot + gets.lenu64() - uint64(i)) - gets[int(i mod gets.lenu64)] = nil + try: + for i in 0'u64..<(checkpointSlot.uint64 + gets.lenu64()): + if not isNil(gets[int(i mod gets.lenu64)]): + await processBlock( + gets[int(i mod gets.lenu64)], + checkpointSlot + gets.lenu64() - uint64(i)) + gets[int(i mod gets.lenu64)] = nil - if i < checkpointSlot: - let slot = checkpointSlot - i - if dbCache.isKnown(slot): - continue + if i < checkpointSlot: + let slot = checkpointSlot - i + if dbCache.isKnown(slot): + continue - gets[int(i mod gets.lenu64)] = downloadBlock(slot) + gets[int(i mod gets.lenu64)] = downloadBlock(slot) - if i mod 1024 == 0: - db.checkpoint() # Transfer stuff from wal periodically - true + if i mod 1024 == 0: + db.checkpoint() # Transfer stuff from wal periodically + true + except CatchableError as exc: # Block download failed + notice "Backfilling incomplete - blocks will be downloaded when starting the node", msg = exc.msg + false else: notice "Database initialized, historical blocks will be backfilled when starting the node", missingSlots diff --git a/beacon_chain/validator_client/api.nim b/beacon_chain/validator_client/api.nim index 3151153fa..1203deb39 100644 --- a/beacon_chain/validator_client/api.nim +++ b/beacon_chain/validator_client/api.nim @@ -557,19 +557,18 @@ template firstSuccessSequential*(vc: ValidatorClientRef, respType: typedesc, if exitNow: break -proc getDutyErrorMessage(response: RestPlainResponse): string = - let res = decodeBytes(RestDutyError, response.data, +proc getIndexedErrorMessage(response: RestPlainResponse): string = + let res = decodeBytes(RestIndexedErrorMessage, response.data, response.contentType) if res.isOk(): let errorObj = res.get() - let failures = errorObj.failures.mapIt(Base10.toString(it.index) & ": " & - it.message) + let failures = errorObj.failures.mapIt($it.index & ": " & it.message) errorObj.message & ": [" & failures.join(", ") & "]" else: "Unable to decode error response: [" & $res.error() & "]" -proc getGenericErrorMessage(response: RestPlainResponse): string = - let res = decodeBytes(RestGenericError, response.data, +proc getErrorMessage(response: RestPlainResponse): string = + let res = decodeBytes(RestErrorMessage, response.data, response.contentType) if res.isOk(): let errorObj = res.get() @@ -1139,15 +1138,15 @@ proc submitPoolAttestations*( RestBeaconNodeStatus.Online of 400: debug ResponseInvalidError, response_code = response.status, - endpoint = node, response_error = response.getDutyErrorMessage() + endpoint = node, response_error = response.getIndexedErrorMessage() RestBeaconNodeStatus.Incompatible of 500: debug ResponseInternalError, response_code = response.status, - endpoint = node, response_error = response.getDutyErrorMessage() + endpoint = node, response_error = response.getIndexedErrorMessage() RestBeaconNodeStatus.Offline else: debug ResponseUnexpectedError, response_code = response.status, - endpoint = node, response_error = response.getDutyErrorMessage() + endpoint = node, response_error = response.getIndexedErrorMessage() RestBeaconNodeStatus.Offline if res.isErr(): raise newException(ValidatorApiError, res.error()) @@ -1168,15 +1167,15 @@ proc submitPoolAttestations*( return true of 400: debug ResponseInvalidError, response_code = response.status, - endpoint = node, response_error = response.getDutyErrorMessage() + endpoint = node, response_error = response.getIndexedErrorMessage() RestBeaconNodeStatus.Incompatible of 500: debug ResponseInternalError, response_code = response.status, - endpoint = node, response_error = response.getDutyErrorMessage() + endpoint = node, response_error = response.getIndexedErrorMessage() RestBeaconNodeStatus.Offline else: debug ResponseUnexpectedError, response_code = response.status, - endpoint = node, response_error = response.getDutyErrorMessage() + endpoint = node, response_error = response.getIndexedErrorMessage() RestBeaconNodeStatus.Offline raise newException(ValidatorApiError, ErrorMessage) @@ -1217,15 +1216,15 @@ proc submitPoolSyncCommitteeSignature*( RestBeaconNodeStatus.Online of 400: debug ResponseInvalidError, response_code = response.status, - endpoint = node, response_error = response.getDutyErrorMessage() + endpoint = node, response_error = response.getIndexedErrorMessage() RestBeaconNodeStatus.Incompatible of 500: debug ResponseInternalError, response_code = response.status, - endpoint = node, response_error = response.getDutyErrorMessage() + endpoint = node, response_error = response.getIndexedErrorMessage() RestBeaconNodeStatus.Offline else: debug ResponseUnexpectedError, response_code = response.status, - endpoint = node, response_error = response.getDutyErrorMessage() + endpoint = node, response_error = response.getIndexedErrorMessage() RestBeaconNodeStatus.Offline if res.isErr(): raise newException(ValidatorApiError, res.error()) @@ -1246,15 +1245,15 @@ proc submitPoolSyncCommitteeSignature*( return true of 400: debug ResponseInvalidError, response_code = response.status, - endpoint = node, response_error = response.getDutyErrorMessage() + endpoint = node, response_error = response.getIndexedErrorMessage() RestBeaconNodeStatus.Incompatible of 500: debug ResponseInternalError, response_code = response.status, - endpoint = node, response_error = response.getDutyErrorMessage() + endpoint = node, response_error = response.getIndexedErrorMessage() RestBeaconNodeStatus.Offline else: debug ResponseUnexpectedError, response_code = response.status, - endpoint = node, response_error = response.getDutyErrorMessage() + endpoint = node, response_error = response.getIndexedErrorMessage() RestBeaconNodeStatus.Offline raise newException(ValidatorApiError, ErrorMessage) @@ -1434,17 +1433,17 @@ proc publishAggregateAndProofs*( of 400: debug ResponseInvalidError, response_code = response.status, endpoint = node, - response_error = response.getGenericErrorMessage() + response_error = response.getErrorMessage() RestBeaconNodeStatus.Incompatible of 500: debug ResponseInternalError, response_code = response.status, endpoint = node, - response_error = response.getGenericErrorMessage() + response_error = response.getErrorMessage() RestBeaconNodeStatus.Offline else: debug ResponseUnexpectedError, response_code = response.status, endpoint = node, - response_error = response.getGenericErrorMessage() + response_error = response.getErrorMessage() RestBeaconNodeStatus.Offline if res.isErr(): raise newException(ValidatorApiError, res.error()) @@ -1466,17 +1465,17 @@ proc publishAggregateAndProofs*( of 400: debug ResponseInvalidError, response_code = response.status, endpoint = node, - response_error = response.getGenericErrorMessage() + response_error = response.getErrorMessage() RestBeaconNodeStatus.Incompatible of 500: debug ResponseInternalError, response_code = response.status, endpoint = node, - response_error = response.getGenericErrorMessage() + response_error = response.getErrorMessage() RestBeaconNodeStatus.Offline else: debug ResponseUnexpectedError, response_code = response.status, endpoint = node, - response_error = response.getGenericErrorMessage() + response_error = response.getErrorMessage() RestBeaconNodeStatus.Offline raise newException(ValidatorApiError, ErrorMessage) @@ -1511,17 +1510,17 @@ proc publishContributionAndProofs*( of 400: debug ResponseInvalidError, response_code = response.status, endpoint = node, - response_error = response.getGenericErrorMessage() + response_error = response.getErrorMessage() RestBeaconNodeStatus.Incompatible of 500: debug ResponseInternalError, response_code = response.status, endpoint = node, - response_error = response.getGenericErrorMessage() + response_error = response.getErrorMessage() RestBeaconNodeStatus.Offline else: debug ResponseUnexpectedError, response_code = response.status, endpoint = node, - response_error = response.getGenericErrorMessage() + response_error = response.getErrorMessage() RestBeaconNodeStatus.Offline if res.isErr(): @@ -1544,17 +1543,17 @@ proc publishContributionAndProofs*( of 400: debug ResponseInvalidError, response_code = response.status, endpoint = node, - response_error = response.getGenericErrorMessage() + response_error = response.getErrorMessage() RestBeaconNodeStatus.Incompatible of 500: debug ResponseInternalError, response_code = response.status, endpoint = node, - response_error = response.getGenericErrorMessage() + response_error = response.getErrorMessage() RestBeaconNodeStatus.Offline else: debug ResponseUnexpectedError, response_code = response.status, endpoint = node, - response_error = response.getGenericErrorMessage() + response_error = response.getErrorMessage() RestBeaconNodeStatus.Offline raise newException(ValidatorApiError, ErrorMessage) @@ -1681,22 +1680,22 @@ proc publishBlock*( of 400: debug ResponseInvalidError, response_code = response.status, endpoint = node, - response_error = response.getGenericErrorMessage() + response_error = response.getErrorMessage() RestBeaconNodeStatus.Incompatible of 500: debug ResponseInternalError, response_code = response.status, endpoint = node, - response_error = response.getGenericErrorMessage() + response_error = response.getErrorMessage() RestBeaconNodeStatus.Offline of 503: debug ResponseNoSyncError, response_code = response.status, endpoint = node, - response_error = response.getGenericErrorMessage() + response_error = response.getErrorMessage() RestBeaconNodeStatus.NotSynced else: debug ResponseUnexpectedError, response_code = response.status, endpoint = node, - response_error = response.getGenericErrorMessage() + response_error = response.getErrorMessage() RestBeaconNodeStatus.Offline if res.isErr(): raise newException(ValidatorApiError, res.error()) @@ -1728,22 +1727,22 @@ proc publishBlock*( of 400: debug ResponseInvalidError, response_code = response.status, endpoint = node, - response_error = response.getGenericErrorMessage() + response_error = response.getErrorMessage() RestBeaconNodeStatus.Incompatible of 500: debug ResponseInternalError, response_code = response.status, endpoint = node, - response_error = response.getGenericErrorMessage() + response_error = response.getErrorMessage() RestBeaconNodeStatus.Offline of 503: debug ResponseNoSyncError, response_code = response.status, endpoint = node, - response_error = response.getGenericErrorMessage() + response_error = response.getErrorMessage() RestBeaconNodeStatus.NotSynced else: debug ResponseUnexpectedError, response_code = response.status, endpoint = node, - response_error = response.getGenericErrorMessage() + response_error = response.getErrorMessage() RestBeaconNodeStatus.Offline raise newException(ValidatorApiError, ErrorMessage) @@ -1780,22 +1779,22 @@ proc prepareBeaconCommitteeSubnet*( of 400: debug ResponseInvalidError, response_code = response.status, endpoint = node, - response_error = response.getGenericErrorMessage() + response_error = response.getErrorMessage() RestBeaconNodeStatus.Online of 500: debug ResponseInternalError, response_code = response.status, endpoint = node, - response_error = response.getGenericErrorMessage() + response_error = response.getErrorMessage() RestBeaconNodeStatus.Offline of 503: debug ResponseNoSyncError, response_code = response.status, endpoint = node, - response_error = response.getGenericErrorMessage() + response_error = response.getErrorMessage() RestBeaconNodeStatus.NotSynced else: debug ResponseUnexpectedError, response_code = response.status, endpoint = node, - response_error = response.getGenericErrorMessage() + response_error = response.getErrorMessage() RestBeaconNodeStatus.Offline if res.isErr(): raise newException(ValidatorApiError, res.error()) @@ -1817,22 +1816,22 @@ proc prepareBeaconCommitteeSubnet*( of 400: debug ResponseInvalidError, response_code = response.status, endpoint = node, - response_error = response.getGenericErrorMessage() + response_error = response.getErrorMessage() return false of 500: debug ResponseInternalError, response_code = response.status, endpoint = node, - response_error = response.getGenericErrorMessage() + response_error = response.getErrorMessage() RestBeaconNodeStatus.Offline of 503: debug ResponseNoSyncError, response_code = response.status, endpoint = node, - response_error = response.getGenericErrorMessage() + response_error = response.getErrorMessage() RestBeaconNodeStatus.NotSynced else: debug ResponseUnexpectedError, response_code = response.status, endpoint = node, - response_error = response.getGenericErrorMessage() + response_error = response.getErrorMessage() RestBeaconNodeStatus.Offline raise newException(ValidatorApiError, ErrorMessage) @@ -1869,22 +1868,22 @@ proc prepareSyncCommitteeSubnets*( of 400: debug ResponseInvalidError, response_code = response.status, endpoint = node, - response_error = response.getGenericErrorMessage() + response_error = response.getErrorMessage() RestBeaconNodeStatus.Online of 500: debug ResponseInternalError, response_code = response.status, endpoint = node, - response_error = response.getGenericErrorMessage() + response_error = response.getErrorMessage() RestBeaconNodeStatus.Offline of 503: debug ResponseNoSyncError, response_code = response.status, endpoint = node, - response_error = response.getGenericErrorMessage() + response_error = response.getErrorMessage() RestBeaconNodeStatus.NotSynced else: debug ResponseUnexpectedError, response_code = response.status, endpoint = node, - response_error = response.getGenericErrorMessage() + response_error = response.getErrorMessage() RestBeaconNodeStatus.Offline if res.isErr(): raise newException(ValidatorApiError, res.error()) @@ -1906,22 +1905,22 @@ proc prepareSyncCommitteeSubnets*( of 400: debug ResponseInvalidError, response_code = response.status, endpoint = node, - response_error = response.getGenericErrorMessage() + response_error = response.getErrorMessage() return false of 500: debug ResponseInternalError, response_code = response.status, endpoint = node, - response_error = response.getGenericErrorMessage() + response_error = response.getErrorMessage() RestBeaconNodeStatus.Offline of 503: debug ResponseNoSyncError, response_code = response.status, endpoint = node, - response_error = response.getGenericErrorMessage() + response_error = response.getErrorMessage() RestBeaconNodeStatus.NotSynced else: debug ResponseUnexpectedError, response_code = response.status, endpoint = node, - response_error = response.getGenericErrorMessage() + response_error = response.getErrorMessage() RestBeaconNodeStatus.Offline raise newException(ValidatorApiError, ErrorMessage) @@ -1999,21 +1998,21 @@ proc getValidatorsActivity*( debug "Server reports invalid request", response_code = response.status, endpoint = apiResponse.node, - response_error = response.getGenericErrorMessage() + response_error = response.getErrorMessage() apiResponse.node.status = RestBeaconNodeStatus.Incompatible default of 500: debug "Server reports internal error", response_code = response.status, endpoint = apiResponse.node, - response_error = response.getGenericErrorMessage() + response_error = response.getErrorMessage() apiResponse.node.status = RestBeaconNodeStatus.Offline default else: debug "Server reports unexpected error code", response_code = response.status, endpoint = apiResponse.node, - response_error = response.getGenericErrorMessage() + response_error = response.getErrorMessage() apiResponse.node.status = RestBeaconNodeStatus.Offline default diff --git a/tests/test_serialization.nim b/tests/test_serialization.nim index 51b48f72f..09143d75e 100644 --- a/tests/test_serialization.nim +++ b/tests/test_serialization.nim @@ -15,77 +15,77 @@ import ./testutil suite "Serialization/deserialization test suite": - test "RestGenericError parser tests": - proc init(t: typedesc[RestGenericError], status: int, - message: string): RestGenericError = - RestGenericError( - code: uint64(status), message: message, + test "RestErrorMessage parser tests": + proc init(t: typedesc[RestErrorMessage], status: int, + message: string): RestErrorMessage = + RestErrorMessage( + code: status, message: message, stacktraces: none[seq[string]]() ) - proc init(t: typedesc[RestGenericError], status: int, + proc init(t: typedesc[RestErrorMessage], status: int, message: string, - stacktraces: openArray[string]): RestGenericError = - RestGenericError( - code: uint64(status), message: message, + stacktraces: openArray[string]): RestErrorMessage = + RestErrorMessage( + code: status, message: message, stacktraces: some(@stacktraces) ) const GoodTestVectors = [ ( """{"code": 500, "message": "block not found"}""", - RestGenericError.init(500, "block not found") + RestErrorMessage.init(500, "block not found") ), ( """{"code": "600", "message": "block not found"}""", - RestGenericError.init(600, "block not found") + RestErrorMessage.init(600, "block not found") ), ( """{"code": "700", "message": "block not found", "data": "data", "custom": "field"}""", - RestGenericError.init(700, "block not found") + RestErrorMessage.init(700, "block not found") ), ( """{"code":"701", "message": "block not found", "data": "data", "custom": 300}""", - RestGenericError.init(701, "block not found") + RestErrorMessage.init(701, "block not found") ), ( """{"code": "702", "message": "block not found", "data": "data", "custom": {"field1": "value1"}}""", - RestGenericError.init(702, "block not found") + RestErrorMessage.init(702, "block not found") ), ( """{"code": 800, "message": "block not found", "custom": "data", "stacktraces": []}""", - RestGenericError.init(800, "block not found", []) + RestErrorMessage.init(800, "block not found", []) ), ( """{"code": 801, "message": "block not found", "custom": 100, "stacktraces": []}""", - RestGenericError.init(801, "block not found", []) + RestErrorMessage.init(801, "block not found", []) ), ( """{"code": 802, "message": "block not found", "custom": {"field1": "value1"}, "stacktraces": []}""", - RestGenericError.init(802, "block not found", []) + RestErrorMessage.init(802, "block not found", []) ), ( """{"code": "900", "message": "block not found", "stacktraces": ["line1", "line2", "line3"], "custom": "data"}""", - RestGenericError.init(900, "block not found", + RestErrorMessage.init(900, "block not found", ["line1", "line2", "line3"]) ), ( """{"code": "901", "message": "block not found", "stacktraces": ["line1", "line2", "line3"], "custom": 2000}""", - RestGenericError.init(901, "block not found", + RestErrorMessage.init(901, "block not found", ["line1", "line2", "line3"]) ), ( """{"code": "902", "message": "block not found", "stacktraces": ["line1", "line2", "line3"], "custom": {"field1": "value1"}}""", - RestGenericError.init(902, "block not found", + RestErrorMessage.init(902, "block not found", ["line1", "line2", "line3"]) ) ] @@ -119,7 +119,7 @@ suite "Serialization/deserialization test suite": for test in GoodTestVectors: let res = decodeBytes( - RestGenericError, test[0].toOpenArrayByte(0, len(test[0]) - 1), + RestErrorMessage, test[0].toOpenArrayByte(0, len(test[0]) - 1), Opt.some(contentType)) check res.isOk() let response = res.get() @@ -135,10 +135,11 @@ suite "Serialization/deserialization test suite": for test in FailureTestVectors: let res = decodeBytes( - RestGenericError, test.toOpenArrayByte(0, len(test) - 1), + RestErrorMessage, test.toOpenArrayByte(0, len(test) - 1), Opt.some(contentType)) + checkpoint test check res.isErr() - test "RestGenericError writer tests": + test "RestErrorMessage writer tests": proc `==`(a: RestApiResponse, b: string): bool = case a.kind of RestApiResponseKind.Content: