More readable server errors.
This commit is contained in:
parent
bf481f4bbf
commit
201e5ced9c
@ -1,54 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
// RetryProvider
|
|
||||||
//
|
|
||||||
// Wraps an existing Provider to provide retry logic.
|
|
||||||
//
|
|
||||||
// See: https://github.com/ethers-io/ethers.js/issues/427
|
|
||||||
|
|
||||||
|
|
||||||
import { ethers } from "ethers";
|
|
||||||
import { poll } from "@ethersproject/web";
|
|
||||||
|
|
||||||
import { version } from "./_version";
|
|
||||||
|
|
||||||
const logger = new ethers.utils.Logger(version);
|
|
||||||
|
|
||||||
export type RetryOptions = {
|
|
||||||
// Maximum time in total to retry
|
|
||||||
timeout?: number,
|
|
||||||
|
|
||||||
// Minimum Duration to wait between retries
|
|
||||||
floor?: number,
|
|
||||||
|
|
||||||
// Maximum Duration to wait between retries
|
|
||||||
ceiling?: number,
|
|
||||||
|
|
||||||
// The slot interval for exponential back-off
|
|
||||||
interval?: number,
|
|
||||||
|
|
||||||
// Maximum number of times to rety
|
|
||||||
retryLimit?: number
|
|
||||||
};
|
|
||||||
|
|
||||||
export class RetryProvider extends ethers.providers.BaseProvider {
|
|
||||||
readonly provider: ethers.providers.BaseProvider;
|
|
||||||
readonly options: RetryOptions;
|
|
||||||
|
|
||||||
constructor(provider: ethers.providers.BaseProvider, options?: RetryOptions) {
|
|
||||||
logger.checkNew(new.target, RetryProvider);
|
|
||||||
super(provider.getNetwork());
|
|
||||||
ethers.utils.defineReadOnly(this, "provider", provider);
|
|
||||||
ethers.utils.defineReadOnly(this, "options", options || { });
|
|
||||||
}
|
|
||||||
|
|
||||||
perform(method: string, params: any): Promise<any> {
|
|
||||||
return poll(() => {
|
|
||||||
return this.provider.perform(method, params).then((result) => {
|
|
||||||
return result
|
|
||||||
}, (error) => {
|
|
||||||
return undefined
|
|
||||||
});
|
|
||||||
}, this.options);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,7 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
import { encode as base64Encode } from "@ethersproject/base64";
|
import { encode as base64Encode } from "@ethersproject/base64";
|
||||||
|
import { hexlify, isBytesLike } from "@ethersproject/bytes";
|
||||||
import { shallowCopy } from "@ethersproject/properties";
|
import { shallowCopy } from "@ethersproject/properties";
|
||||||
import { toUtf8Bytes, toUtf8String } from "@ethersproject/strings";
|
import { toUtf8Bytes, toUtf8String } from "@ethersproject/strings";
|
||||||
|
|
||||||
@ -16,6 +17,23 @@ function staller(duration: number): Promise<void> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function bodyify(value: any, type: string): string {
|
||||||
|
if (value == null) { return null; }
|
||||||
|
|
||||||
|
if (typeof(value) === "string") { return value; }
|
||||||
|
|
||||||
|
if (isBytesLike(value)) {
|
||||||
|
if (type && (type.split("/")[0] === "text" || type === "application/json")) {
|
||||||
|
try {
|
||||||
|
return toUtf8String(value);
|
||||||
|
} catch (error) { };
|
||||||
|
}
|
||||||
|
return hexlify(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
// Exported Types
|
// Exported Types
|
||||||
export type ConnectionInfo = {
|
export type ConnectionInfo = {
|
||||||
url: string,
|
url: string,
|
||||||
@ -154,7 +172,7 @@ export function _fetchData<T = Uint8Array>(connection: string | ConnectionInfo,
|
|||||||
timer = null;
|
timer = null;
|
||||||
|
|
||||||
reject(logger.makeError("timeout", Logger.errors.TIMEOUT, {
|
reject(logger.makeError("timeout", Logger.errors.TIMEOUT, {
|
||||||
requestBody: (options.body || null),
|
requestBody: bodyify(options.body, flatHeaders["content-type"]),
|
||||||
requestMethod: options.method,
|
requestMethod: options.method,
|
||||||
timeout: timeout,
|
timeout: timeout,
|
||||||
url: url
|
url: url
|
||||||
@ -208,7 +226,7 @@ export function _fetchData<T = Uint8Array>(connection: string | ConnectionInfo,
|
|||||||
if (response == null) {
|
if (response == null) {
|
||||||
runningTimeout.cancel();
|
runningTimeout.cancel();
|
||||||
logger.throwError("missing response", Logger.errors.SERVER_ERROR, {
|
logger.throwError("missing response", Logger.errors.SERVER_ERROR, {
|
||||||
requestBody: (options.body || null),
|
requestBody: bodyify(options.body, flatHeaders["content-type"]),
|
||||||
requestMethod: options.method,
|
requestMethod: options.method,
|
||||||
serverError: error,
|
serverError: error,
|
||||||
url: url
|
url: url
|
||||||
@ -227,8 +245,8 @@ export function _fetchData<T = Uint8Array>(connection: string | ConnectionInfo,
|
|||||||
logger.throwError("bad response", Logger.errors.SERVER_ERROR, {
|
logger.throwError("bad response", Logger.errors.SERVER_ERROR, {
|
||||||
status: response.statusCode,
|
status: response.statusCode,
|
||||||
headers: response.headers,
|
headers: response.headers,
|
||||||
body: body,
|
body: bodyify(body, ((response.headers) ? response.headers["content-type"]: null)),
|
||||||
requestBody: (options.body || null),
|
requestBody: bodyify(options.body, flatHeaders["content-type"]),
|
||||||
requestMethod: options.method,
|
requestMethod: options.method,
|
||||||
url: url
|
url: url
|
||||||
});
|
});
|
||||||
@ -258,9 +276,9 @@ export function _fetchData<T = Uint8Array>(connection: string | ConnectionInfo,
|
|||||||
|
|
||||||
runningTimeout.cancel();
|
runningTimeout.cancel();
|
||||||
logger.throwError("processing response error", Logger.errors.SERVER_ERROR, {
|
logger.throwError("processing response error", Logger.errors.SERVER_ERROR, {
|
||||||
body: body,
|
body: bodyify(body, ((response.headers) ? response.headers["content-type"]: null)),
|
||||||
error: error,
|
error: error,
|
||||||
requestBody: (options.body || null),
|
requestBody: bodyify(options.body, flatHeaders["content-type"]),
|
||||||
requestMethod: options.method,
|
requestMethod: options.method,
|
||||||
url: url
|
url: url
|
||||||
});
|
});
|
||||||
@ -275,7 +293,7 @@ export function _fetchData<T = Uint8Array>(connection: string | ConnectionInfo,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return logger.throwError("failed response", Logger.errors.SERVER_ERROR, {
|
return logger.throwError("failed response", Logger.errors.SERVER_ERROR, {
|
||||||
requestBody: (options.body || null),
|
requestBody: bodyify(options.body, flatHeaders["content-type"]),
|
||||||
requestMethod: options.method,
|
requestMethod: options.method,
|
||||||
url: url
|
url: url
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user