Let RestClient.getContractInfo return null for missing contract

This commit is contained in:
Simon Warta
2020-02-27 23:53:52 +01:00
parent 8674d6815b
commit 836e6a6c5e
5 changed files with 43 additions and 18 deletions
+6 -2
View File
@@ -220,8 +220,12 @@ export class CosmWasmClient {
}));
}
/**
* Throws an error if no contract was found at the address
*/
public async getContract(address: string): Promise<ContractDetails> {
const result = await this.restClient.getContractInfo(address);
if (!result) throw new Error(`No contract found at address "${address}"`);
return {
address: result.address,
codeId: result.code_id,
@@ -238,7 +242,7 @@ export class CosmWasmClient {
*/
public async queryContractRaw(address: string, key: Uint8Array): Promise<Uint8Array | null> {
// just test contract existence
const _info = await this.restClient.getContractInfo(address);
const _info = await this.getContract(address);
return this.restClient.queryContractRaw(address, key);
}
@@ -254,7 +258,7 @@ export class CosmWasmClient {
return await this.restClient.queryContractSmart(address, queryMsg);
} catch (error) {
if (error instanceof Error) {
if (error.message === "not found: contract") {
if (error.message.startsWith("not found: contract")) {
throw new Error(`No contract found at address "${address}"`);
} else {
throw error;
+2 -4
View File
@@ -684,16 +684,14 @@ describe("RestClient", () => {
// check out info
const myInfo = await client.getContractInfo(myAddress);
assert(myInfo);
expect(myInfo.code_id).toEqual(codeId);
expect(myInfo.creator).toEqual(faucet.address);
expect((myInfo.init_msg as any).beneficiary).toEqual(beneficiaryAddress);
// make sure random addresses don't give useful info
const nonExistentAddress = makeRandomAddress();
await client
.getContractInfo(nonExistentAddress)
.then(() => fail("this shouldn't succeed"))
.catch(error => expect(error).toMatch(`No contract found at address "${nonExistentAddress}"`));
expect(await client.getContractInfo(nonExistentAddress)).toBeNull();
});
describe("contract state", () => {
+28 -11
View File
@@ -198,18 +198,20 @@ function unwrapWasmResponse<T>(response: WasmResponse<T>): T {
// We want to get message data from 500 errors
// https://stackoverflow.com/questions/56577124/how-to-handle-500-error-message-with-axios
// this should be chained to catch one error and throw a more informative one
function parseAxios500error(err: AxiosError): never {
function parseAxiosError(err: AxiosError): never {
// use the error message sent from server, not default 500 msg
if (err.response?.data) {
let errorText: string;
const data = err.response.data;
// expect { error: string }, but otherwise dump
if (data.error) {
throw new Error(data.error);
if (data.error && typeof data.error === "string") {
errorText = data.error;
} else if (typeof data === "string") {
throw new Error(data);
errorText = data;
} else {
throw new Error(JSON.stringify(data));
errorText = JSON.stringify(data);
}
throw new Error(`${errorText} (HTTP ${err.response.status})`);
} else {
throw err;
}
@@ -231,7 +233,7 @@ export class RestClient {
}
public async get(path: string): Promise<RestClientResponse> {
const { data } = await this.client.get(path).catch(parseAxios500error);
const { data } = await this.client.get(path).catch(parseAxiosError);
if (data === null) {
throw new Error("Received null response from server");
}
@@ -239,7 +241,7 @@ export class RestClient {
}
public async post(path: string, params: PostTxsParams): Promise<RestClientResponse> {
const { data } = await this.client.post(path, params).catch(parseAxios500error);
const { data } = await this.client.post(path, params).catch(parseAxiosError);
if (data === null) {
throw new Error("Received null response from server");
}
@@ -355,11 +357,26 @@ export class RestClient {
return unwrapWasmResponse(responseData) || [];
}
// throws error if no contract at this address
public async getContractInfo(address: string): Promise<ContractDetails> {
/**
* Returns null when contract was not found at this address.
*/
public async getContractInfo(address: string): Promise<ContractDetails | null> {
const path = `/wasm/contract/${address}`;
const responseData = (await this.get(path)) as WasmResponse<ContractDetails>;
return unwrapWasmResponse(responseData);
try {
const response = (await this.get(path)) as WasmResponse<ContractDetails>;
return unwrapWasmResponse(response);
} catch (error) {
if (error instanceof Error) {
if (error.message.startsWith("unknown address:")) {
return null;
} else {
throw error;
}
} else {
throw error;
}
}
}
// Returns all contract state.
+3
View File
@@ -76,6 +76,9 @@ export declare class CosmWasmClient {
getCodes(): Promise<readonly Code[]>;
getCodeDetails(codeId: number): Promise<CodeDetails>;
getContracts(codeId: number): Promise<readonly Contract[]>;
/**
* Throws an error if no contract was found at the address
*/
getContract(address: string): Promise<ContractDetails>;
/**
* Returns the data at the key if present (raw contract dependent storage data)
+4 -1
View File
@@ -165,7 +165,10 @@ export declare class RestClient {
listCodeInfo(): Promise<readonly CodeInfo[]>;
getCode(id: number): Promise<Uint8Array>;
listContractsByCodeId(id: number): Promise<readonly ContractInfo[]>;
getContractInfo(address: string): Promise<ContractDetails>;
/**
* Returns null when contract was not found at this address.
*/
getContractInfo(address: string): Promise<ContractDetails | null>;
getAllContractState(address: string): Promise<readonly Model[]>;
queryContractRaw(address: string, key: Uint8Array): Promise<Uint8Array | null>;
queryContractSmart(address: string, query: object): Promise<Uint8Array>;