Skip to content

Commit 32f3eaf

Browse files
hsy822Aniket-Engg
authored andcommitted
fix error handling
1 parent b56bf22 commit 32f3eaf

File tree

3 files changed

+63
-46
lines changed

3 files changed

+63
-46
lines changed

apps/contract-verification/src/app/ContractVerificationPluginClient.ts

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -78,14 +78,16 @@ export class ContractVerificationPluginClient extends PluginClient {
7878
return
7979
}
8080

81-
await this.call('terminal', 'log', { type: 'info', value: `[Verification] Contract deployed. Checking explorers for registration...` });
81+
await this.call('terminal', 'log', { type: 'info', value: `[Verification] Contract deployed. Checking explorers for registration...` })
82+
83+
await new Promise(resolve => setTimeout(resolve, 5000))
8284

8385
try {
8486
const allArtifacts = await this.call('compilerArtefacts' as any, 'getAllCompilerAbstracts')
8587
const compilerAbstract = allArtifacts ? allArtifacts[filePath] : undefined
8688

8789
if (!compilerAbstract) {
88-
await this.call('terminal', 'log', { type: 'error', value: `[Verification] Artifacts not found for ${contractName}.` })
90+
await this.call('terminal', 'log', { type: 'warn', value: `[Verification] Artifacts not found for ${contractName}.` })
8991
return
9092
}
9193

@@ -195,8 +197,13 @@ export class ContractVerificationPluginClient extends PluginClient {
195197
isExplorerReady = true
196198
break
197199
} catch (lookupError: any) {
198-
const errMsg = lookupError.message || ''
199-
if (errMsg.includes('does not exist') || errMsg.includes('Unable to locate ContractCode') || errMsg.includes('not found')) {
200+
let errMsg = lookupError.message || ''
201+
202+
if (errMsg.trim().startsWith('<') || errMsg.includes('<!DOCTYPE html>')) {
203+
errMsg = 'Explorer API Error (500)'
204+
}
205+
206+
if (errMsg.includes('does not exist') || errMsg.includes('Unable to locate ContractCode') || errMsg.includes('not found') || errMsg.includes('500') || errMsg.includes('404')) {
200207
await new Promise(r => setTimeout(r, 3000))
201208
continue
202209
}
@@ -206,7 +213,7 @@ export class ContractVerificationPluginClient extends PluginClient {
206213

207214
if (!isExplorerReady) {
208215
const msg = `Contract not found on ${verifierId} after 30s. Explorer indexing timed out.`
209-
await this.call('terminal', 'log', { type: 'error', value: `[${verifierId}] ${msg}` })
216+
await this.call('terminal', 'log', { type: 'warn', value: `[${verifierId}] ${msg}` })
210217
await this.updateReceiptStatus(contractId, verifierId, { status: 'failed', message: msg })
211218
return
212219
}
@@ -238,11 +245,11 @@ export class ContractVerificationPluginClient extends PluginClient {
238245
}
239246
} else if (result.status === 'failed') {
240247
const msg = result.message || 'Unknown failure'
241-
await this.call('terminal', 'log', { type: 'error', value: `[${verifierId}] Verification Failed: ${msg}` })
248+
await this.call('terminal', 'log', { type: 'warn', value: `[${verifierId}] Verification Failed: ${msg}` })
242249
await this.call('terminal', 'log', { type: 'warn', value: `[${verifierId}] Please open the "Contract Verification" plugin to retry.` })
243250

244251
if (verifierId === 'Etherscan' && !pluginApiKey) {
245-
await this.call('terminal', 'log', { type: 'warn', value: `Note: To retry Etherscan verification in the plugin, you must save your API key in the plugin settings.` })
252+
await this.call('terminal', 'log', { type: 'info', value: `Note: To retry Etherscan verification in the plugin, you must save your API key in the plugin settings.` })
246253
}
247254
} else if (result.status === 'pending' && result.receiptId) {
248255
await this.call('terminal', 'log', { type: 'log', value: `[${verifierId}] Verification submitted. Awaiting confirmation...` })
@@ -252,19 +259,19 @@ export class ContractVerificationPluginClient extends PluginClient {
252259
let errorMsg = error.message || 'Unknown error'
253260

254261
if (errorMsg.trim().startsWith('<') || errorMsg.includes('<!DOCTYPE html>')) {
255-
errorMsg = 'Explorer API returned an Internal Server Error (500). Service might be unstable.';
262+
errorMsg = 'Explorer API Error (500)'
256263
}
257264

258265
await this.updateReceiptStatus(contractId, verifierId, {
259266
status: 'failed',
260267
message: errorMsg
261268
})
262269

263-
await this.call('terminal', 'log', { type: 'error', value: `[${verifierId}] Verification Error: ${errorMsg}` })
270+
await this.call('terminal', 'log', { type: 'warn', value: `[${verifierId}] Verification Error: ${errorMsg}` })
264271
await this.call('terminal', 'log', { type: 'warn', value: `[${verifierId}] Please open the "Contract Verification" plugin to retry.` })
265272

266273
if (verifierId === 'Etherscan' && !pluginApiKey) {
267-
await this.call('terminal', 'log', { type: 'warn', value: `Note: To retry Etherscan verification in the plugin, you must save your API key in the plugin settings.` })
274+
await this.call('terminal', 'log', { type: 'info', value: `Note: To retry Etherscan verification in the plugin, you must save your API key in the plugin settings.` })
268275
}
269276
}
270277
}

apps/contract-verification/src/app/app.tsx

Lines changed: 36 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ const App = () => {
2424
const [chains, setChains] = useState<Chain[]>([])
2525
const [compilationOutput, setCompilationOutput] = useState<{ [key: string]: CompilerAbstract } | undefined>()
2626

27-
// Form values:
2827
const [selectedChain, setSelectedChain] = useState<Chain | undefined>()
2928
const [contractAddress, setContractAddress] = useState('')
3029
const [contractAddressError, setContractAddressError] = useState('')
@@ -46,16 +45,13 @@ const App = () => {
4645
plugin.call('locale', 'currentLocale').then((locale: any) => {
4746
setLocale(locale)
4847
})
49-
5048
// @ts-ignore
5149
plugin.on('locale', 'localeChanged', (locale: any) => {
5250
setLocale(locale)
5351
})
54-
5552
plugin.call('compilerArtefacts' as any, 'getAllCompilerAbstracts').then((obj: any) => {
5653
setCompilationOutput(obj)
5754
})
58-
5955
plugin.on('compilerArtefacts' as any, 'compilationSaved', (compilerAbstracts: { [key: string]: CompilerAbstract }) => {
6056
setCompilationOutput((prev) => ({ ...(prev || {}), ...compilerAbstracts }))
6157
})
@@ -117,16 +113,16 @@ const App = () => {
117113

118114
const pollStatus = async () => {
119115
const changedSubmittedContracts = { ...submittedContracts }
120-
const now = new Date().getTime()
121116

122117
for (const receipt of pendingReceipts) {
123118
await new Promise((resolve) => setTimeout(resolve, 500))
124119

125120
const { verifierInfo, receiptId, contractId } = receipt
126-
127121
const contract = changedSubmittedContracts[contractId]
128-
const submissionTime = new Date(contract.date).getTime()
129-
const isTimedOut = (now - submissionTime) > 30000
122+
123+
if (receipt.failedChecks >= 10) {
124+
receipt.failedChecks = 0
125+
}
130126

131127
if (receiptId) {
132128
const chainSettings = mergeChainSettingsWithDefaults(contract.chainId, settings)
@@ -170,46 +166,45 @@ const App = () => {
170166
response = await verifier.checkVerificationStatus(receiptId, contract.chainId)
171167
}
172168

169+
if (response.status === 'pending') {
170+
receipt.failedChecks++
171+
}
172+
173+
if (receipt.failedChecks >= 10) {
174+
response.status = 'failed'
175+
response.message = 'Verification timed out (30s limit).'
176+
}
173177

174178
const { status, message, lookupUrl } = response
175179
const prevStatus = receipt.status
176180

177-
if (status === 'pending' && isTimedOut) {
178-
receipt.status = 'failed'
179-
receipt.message = 'Verification timed out (30s).'
180-
181-
plugin.call('terminal', 'log', { type: 'warn', value: `[${verifierInfo.name}] Polling timed out. Please check the explorer manually.` })
182-
183-
if (contract.address && verifierInfo.name === 'Blockscout') {
184-
plugin.call('terminal', 'log', { type: 'info', value: `Blockscout often verifies silently. Check here: https://eth-sepolia.blockscout.com/address/${contract.address}?tab=contract` })
185-
}
186-
} else {
187-
receipt.status = status
188-
receipt.message = message
189-
if (lookupUrl) {
190-
receipt.lookupUrl = lookupUrl
191-
}
181+
receipt.status = status
182+
receipt.message = message
183+
if (lookupUrl) {
184+
receipt.lookupUrl = lookupUrl
192185
}
193186

194-
if (prevStatus === 'pending' && receipt.status !== 'pending') {
195-
const finalStatus = receipt.status
187+
if (prevStatus === 'pending' && status !== 'pending') {
196188
const successStatuses = ['verified', 'partially verified', 'already verified', 'exactly verified', 'fully verified']
197189

198-
if (successStatuses.includes(finalStatus)) {
190+
if (successStatuses.includes(status)) {
199191
if (receipt.lookupUrl) {
200192
const htmlContent = `<span class="text-success">[${verifierInfo.name}] Verification Successful!</span> &nbsp;<a href="${receipt.lookupUrl}" target="_blank">View Code</a>`
201193
await plugin.call('terminal' as any, 'logHtml', { value: htmlContent })
202194
} else {
203195
const htmlContent = `<span class="text-success">[${verifierInfo.name}] Verification Successful!</span>`
204196
await plugin.call('terminal' as any, 'logHtml', { value: htmlContent })
205197
}
206-
} else if (finalStatus === 'failed') {
207-
if (receipt.message !== 'Verification timed out (30s).') {
208-
plugin.call('terminal', 'log', { type: 'warn', value: `[${verifierInfo.name}] Verification Failed: Please open the "Contract Verification" plugin to retry.` })
198+
} else if (status === 'failed') {
199+
if (message === 'Verification timed out (30s limit).') {
200+
plugin.call('terminal', 'log', { type: 'warn', value: `[${verifierInfo.name}] Polling timed out. Please open the "Contract Verification" plugin to check details.` })
201+
} else {
202+
plugin.call('terminal', 'log', { type: 'warn', value: `[${verifierInfo.name}] Verification Failed: ${message || 'Unknown reason'}` })
203+
plugin.call('terminal', 'log', { type: 'warn', value: `Please open the "Contract Verification" plugin to retry.` })
209204
}
210205

211206
if (verifierInfo.name === 'Etherscan' && !chainSettings.verifiers['Etherscan']?.apiKey) {
212-
plugin.call('terminal', 'log', { type: 'warn', value: `Note: To retry Etherscan verification in the plugin, you must save your API key in the plugin settings.` })
207+
plugin.call('terminal', 'log', { type: 'info', value: `Note: To retry Etherscan verification in the plugin, you must save your API key in the plugin settings.` })
213208
}
214209
}
215210
}
@@ -219,19 +214,25 @@ const App = () => {
219214
let errorMsg = e.message || 'Unknown error'
220215

221216
if (errorMsg.trim().startsWith('<') || errorMsg.includes('<!DOCTYPE html>')) {
222-
errorMsg = 'Explorer API Error (500)'
217+
errorMsg = 'Explorer API Error (500)';
218+
}
219+
if (errorMsg.includes('404')) {
220+
errorMsg = 'Pending registration (404)';
223221
}
224222

225-
// Only retry 10 times
226223
if (receipt.failedChecks >= 10) {
227224
receipt.status = 'failed'
228225
receipt.message = errorMsg
229226

230-
plugin.call('terminal', 'log', { type: 'warn', value: `[${verifierInfo.name}] Verification Failed after ${receipt.failedChecks} attempts: ${errorMsg}` })
231-
plugin.call('terminal', 'log', { type: 'warn', value: `Please open the "Contract Verification" plugin to retry.` })
227+
if (errorMsg.includes('404')) {
228+
plugin.call('terminal', 'log', { type: 'warn', value: `[${verifierInfo.name}] Polling timed out (404). Please open the "Contract Verification" plugin to check details.` })
229+
} else {
230+
plugin.call('terminal', 'log', { type: 'warn', value: `[${verifierInfo.name}] Verification Failed after ${receipt.failedChecks} attempts: ${errorMsg}` })
231+
plugin.call('terminal', 'log', { type: 'warn', value: `Please open the "Contract Verification" plugin to retry.` })
232+
}
232233

233234
if (verifierInfo.name === 'Etherscan' && !chainSettings.verifiers['Etherscan']?.apiKey) {
234-
plugin.call('terminal', 'log', { type: 'warn', value: `Note: To retry Etherscan verification in the plugin, you must save your API key in the plugin settings.` })
235+
plugin.call('terminal', 'log', { type: 'info', value: `Note: To retry Etherscan verification in the plugin, you must save your API key in the plugin settings.` })
235236
}
236237
}
237238
}

apps/contract-verification/src/app/components/AccordionReceipt.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ interface AccordionReceiptProps {
1313
}
1414

1515
export const AccordionReceipt: React.FC<AccordionReceiptProps> = ({ contract, index }) => {
16-
const { chains, settings, compilationOutput, setSubmittedContracts } = React.useContext(AppContext)
16+
const { chains, settings, compilationOutput, setSubmittedContracts, clientInstance } = React.useContext(AppContext)
1717

1818
const [expanded, setExpanded] = React.useState(false)
1919

@@ -93,6 +93,15 @@ export const AccordionReceipt: React.FC<AccordionReceiptProps> = ({ contract, in
9393
])
9494
}
9595

96+
const successStatuses = ['verified', 'partially verified', 'already verified', 'exactly verified', 'fully verified']
97+
98+
if (successStatuses.includes(response.status)) {
99+
const link = response.lookupUrl ? `&nbsp;<a href="${response.lookupUrl}" target="_blank">View Code</a>` : '';
100+
const htmlContent = `<span class="text-success">[${receipt.verifierInfo.name}] Verification Successful!</span> ${link}`;
101+
102+
await clientInstance.call('terminal' as any, 'logHtml', { value: htmlContent });
103+
}
104+
96105
setSubmittedContracts(prev => {
97106
const currentContract = prev[contract.id]
98107
if (!currentContract) return prev

0 commit comments

Comments
 (0)