Skip to content

Commit c40b129

Browse files
authored
Merge PR #287 from webwarrior-ws/weird-null-response-exn
Backend/Ether: handle null response from Eth server.
2 parents 9c082a9 + f05dd7a commit c40b129

File tree

3 files changed

+42
-7
lines changed

3 files changed

+42
-7
lines changed

src/GWallet.Backend/Ether/EtherExceptions.fs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ type RpcErrorCode =
3333
| CannotFulfillRequest = -32046
3434
| ResourceNotFound = -32001
3535
| InternalError = -32603
36+
| UnparsableResponseType = -39000
3637

3738
type ServerCannotBeResolvedException =
3839
inherit CommunicationUnsuccessfulException
@@ -95,3 +96,10 @@ type UnhandledWebException =
9596
}
9697
new (info: SerializationInfo, context: StreamingContext) =
9798
{ inherit Exception (info, context) }
99+
100+
/// Exception indicating that response JSON contains null value where it should not.
101+
/// E.g. {"jsonrpc":"2.0","id":1,"result":null}
102+
type AbnormalNullValueInJsonResponseException(message: string) =
103+
inherit CommunicationUnsuccessfulException(message)
104+
105+
static member BalanceJobErrorMessage = "Abnormal null response from balance job"

src/GWallet.Backend/Ether/EtherServer.fs

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,8 @@ module Server =
136136
raise <| ServerTimedOutException(exMsg, httpReqEx)
137137
if HttpRequestExceptionMatchesErrorCode httpReqEx (int CloudFlareError.OriginUnreachable) then
138138
raise <| ServerTimedOutException(exMsg, httpReqEx)
139+
if HttpRequestExceptionMatchesErrorCode httpReqEx (int HttpStatusCode.RequestTimeout) then
140+
raise <| ServerTimedOutException(exMsg, httpReqEx)
139141

140142
if HttpRequestExceptionMatchesErrorCode httpReqEx (int CloudFlareError.OriginSslHandshakeError) then
141143
raise <| ServerChannelNegotiationException(exMsg, CloudFlareError.OriginSslHandshakeError, httpReqEx)
@@ -226,6 +228,8 @@ module Server =
226228
raise <| ServerMisconfiguredException(exMsg, rpcResponseEx)
227229
| i when i = int RpcErrorCode.InternalError ->
228230
raise <| ServerFaultException(exMsg, rpcResponseEx)
231+
| j when j = int RpcErrorCode.UnparsableResponseType ->
232+
raise <| ServerFaultException(exMsg, rpcResponseEx)
229233
| _ ->
230234
raise
231235
<| Exception (SPrintF3 "RpcResponseException with RpcError Code <%i> and Message '%s' (%s)"
@@ -464,7 +468,10 @@ module Server =
464468
let! cancelToken = Async.CancellationToken
465469
let task =
466470
web3.Eth.Transactions.GetTransactionCount.SendRequestAsync(address, null, cancelToken)
467-
return! Async.AwaitTask task
471+
let! txCount = Async.AwaitTask task
472+
if isNull txCount then
473+
raise <| AbnormalNullValueInJsonResponseException "Abnormal null response from tx count job"
474+
return txCount
468475
}
469476
GetRandomizedFuncs currency web3Func
470477
return! faultTolerantEtherClient.Query
@@ -480,7 +487,7 @@ module Server =
480487
web3.Eth.Blocks.GetBlockNumber.SendRequestAsync (null, cancelToken)
481488
|> Async.AwaitTask
482489
if isNull latestBlock then
483-
failwith "latestBlock somehow is null"
490+
raise <| AbnormalNullValueInJsonResponseException "latestBlock somehow is null"
484491

485492
let blockToCheck = BigInteger.Subtract(latestBlock.Value,
486493
NUMBER_OF_CONFIRMATIONS_TO_CONSIDER_BALANCE_CONFIRMED)
@@ -542,8 +549,10 @@ module Server =
542549
let task = web3.Eth.GetBalance.SendRequestAsync (address, null, cancelToken)
543550
return! Async.AwaitTask task
544551
}
545-
if Object.ReferenceEquals(balance, null) then
546-
failwith "Weird null response from balance job"
552+
if isNull balance then
553+
raise <|
554+
AbnormalNullValueInJsonResponseException
555+
AbnormalNullValueInJsonResponseException.BalanceJobErrorMessage
547556
return UnitConversion.Convert.FromWei(balance.Value, UnitConversion.EthUnit.Ether)
548557
}
549558
GetRandomizedFuncs currency web3Func
@@ -573,7 +582,7 @@ module Server =
573582

574583
let contractHandler = web3.Eth.GetContractHandler contractAddress
575584
if isNull contractHandler then
576-
failwith "contractHandler somehow is null"
585+
raise <| AbnormalNullValueInJsonResponseException "contractHandler somehow is null"
577586

578587
let! cancelToken = Async.CancellationToken
579588
cancelToken.ThrowIfCancellationRequested()
@@ -635,7 +644,10 @@ module Server =
635644
let! cancelToken = Async.CancellationToken
636645
let task =
637646
contractHandler.EstimateGasAsync<TransferFunction>(transferFunctionMsg, cancelToken)
638-
return! Async.AwaitTask task
647+
let! fee = Async.AwaitTask task
648+
if isNull fee then
649+
raise <| AbnormalNullValueInJsonResponseException "Abnormal null response from transfer fee job"
650+
return fee
639651
}
640652
GetRandomizedFuncs account.Currency web3Func
641653
return! faultTolerantEtherClient.Query
@@ -658,6 +670,8 @@ module Server =
658670
let! cancelToken = Async.CancellationToken
659671
let task = web3.Eth.GasPrice.SendRequestAsync(null, cancelToken)
660672
let! hexBigInteger = Async.AwaitTask task
673+
if isNull hexBigInteger then
674+
raise <| AbnormalNullValueInJsonResponseException "Abnormal null response from gas price job"
661675
if hexBigInteger.Value = BigInteger 0 then
662676
return failwith "Some server returned zero for gas price, which is invalid"
663677
return hexBigInteger
@@ -688,7 +702,12 @@ module Server =
688702
let! cancelToken = Async.CancellationToken
689703
let task =
690704
web3.Eth.Transactions.SendRawTransaction.SendRequestAsync(transaction, null, cancelToken)
691-
return! Async.AwaitTask task
705+
let! response = Async.AwaitTask task
706+
if isNull response then
707+
raise <|
708+
AbnormalNullValueInJsonResponseException
709+
"Abnormal null response from broadcast transaction job"
710+
return response
692711
}
693712
GetRandomizedFuncs currency web3Func
694713
try
@@ -719,6 +738,10 @@ module Server =
719738
let task =
720739
web3.TransactionManager.TransactionReceiptService.PollForReceiptAsync(txHash, cancelToken)
721740
let! transactionReceipt = Async.AwaitTask task
741+
if isNull transactionReceipt || isNull transactionReceipt.GasUsed || isNull transactionReceipt.Status then
742+
raise <|
743+
AbnormalNullValueInJsonResponseException
744+
(SPrintF1 "Abnormal null response when getting details from tx receipt (%A)" transactionReceipt)
722745
return {
723746
GasUsed = transactionReceipt.GasUsed.Value
724747
Status = transactionReceipt.Status.Value

src/GWallet.Backend/ServerManager.fs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,10 @@ module ServerManager =
128128
let web3Func (web3: Ether.SomeWeb3): Async<decimal> =
129129
async {
130130
let! balance = Async.AwaitTask (web3.Eth.GetBalance.SendRequestAsync ETH_GENESISBLOCK_ADDRESS)
131+
if isNull balance then
132+
raise <|
133+
Ether.AbnormalNullValueInJsonResponseException
134+
Ether.AbnormalNullValueInJsonResponseException.BalanceJobErrorMessage
131135
return balance.Value |> decimal
132136
}
133137

0 commit comments

Comments
 (0)