@@ -6,6 +6,11 @@ import utils from '../utils';
66import Upload from '../upload' ;
77import platform from '../utils/platform' ;
88import logger from '../logger' ;
9+ import { handleAxiosError , isNetworkError } from '../utils/error-helpers' ;
10+ import {
11+ checkInternetConnectivity ,
12+ formatConnectivityResults ,
13+ } from '../utils/connectivity' ;
914
1015/**
1116 * Common interface for run information shared by all providers
@@ -208,7 +213,8 @@ export default abstract class BaseProvider<
208213 }
209214
210215 /**
211- * Extracts an error message from various error types
216+ * Extracts an error message from various error types.
217+ * For Axios errors, uses enhanced error handling with diagnostics.
212218 */
213219 protected extractErrorMessage ( cause : unknown ) : string | null {
214220 if ( typeof cause === 'string' ) {
@@ -220,7 +226,14 @@ export default abstract class BaseProvider<
220226 }
221227
222228 if ( cause && typeof cause === 'object' ) {
223- const axiosError = cause as {
229+ // Use enhanced error handling for real Axios errors
230+ if ( axios . isAxiosError ( cause ) ) {
231+ const enhanced = handleAxiosError ( cause , 'Request failed' ) ;
232+ return enhanced . message ;
233+ }
234+
235+ // Handle error-like objects with response property (for backwards compatibility)
236+ const axiosLikeError = cause as {
224237 response ?: {
225238 status ?: number ;
226239 data ?: { error ?: string ; errors ?: string [ ] ; message ?: string } ;
@@ -229,18 +242,19 @@ export default abstract class BaseProvider<
229242 } ;
230243
231244 // Check for 429 status code (credits depleted)
232- if ( axiosError . response ?. status === 429 ) {
245+ if ( axiosLikeError . response ?. status === 429 ) {
233246 return 'Your TestingBot credits are depleted. Please upgrade your plan at https://testingbot.com/pricing' ;
234247 }
235248
236- if ( axiosError . response ?. data ?. errors ) {
237- return axiosError . response . data . errors . join ( '\n' ) ;
249+ // Extract error message from response data
250+ if ( axiosLikeError . response ?. data ?. errors ) {
251+ return axiosLikeError . response . data . errors . join ( '\n' ) ;
238252 }
239- if ( axiosError . response ?. data ?. error ) {
240- return axiosError . response . data . error ;
253+ if ( axiosLikeError . response ?. data ?. error ) {
254+ return axiosLikeError . response . data . error ;
241255 }
242- if ( axiosError . response ?. data ?. message ) {
243- return axiosError . response . data . message ;
256+ if ( axiosLikeError . response ?. data ?. message ) {
257+ return axiosLikeError . response . data . message ;
244258 }
245259
246260 if ( cause instanceof Error ) {
@@ -266,6 +280,58 @@ export default abstract class BaseProvider<
266280 return null ;
267281 }
268282
283+ /**
284+ * Checks internet connectivity and logs diagnostic information.
285+ * Useful when network errors occur to help users troubleshoot.
286+ */
287+ protected async checkAndReportConnectivity ( ) : Promise < boolean > {
288+ logger . info ( 'Checking internet connectivity...' ) ;
289+ const result = await checkInternetConnectivity ( ) ;
290+ logger . info ( formatConnectivityResults ( result ) ) ;
291+ return result . connected ;
292+ }
293+
294+ /**
295+ * Performs a quick connectivity check before starting operations.
296+ * Throws an error with diagnostics if no connection is available.
297+ */
298+ protected async ensureConnectivity ( ) : Promise < void > {
299+ const result = await checkInternetConnectivity ( ) ;
300+ if ( ! result . connected ) {
301+ logger . error ( 'No internet connection detected.' ) ;
302+ logger . error ( formatConnectivityResults ( result ) ) ;
303+ throw new TestingBotError (
304+ 'No internet connection. Please check your network and try again.' ,
305+ ) ;
306+ }
307+ }
308+
309+ /**
310+ * Handles errors with enhanced diagnostics.
311+ * For network errors, performs connectivity check.
312+ */
313+ protected async handleErrorWithDiagnostics (
314+ error : unknown ,
315+ operation : string ,
316+ ) : Promise < TestingBotError > {
317+ if ( axios . isAxiosError ( error ) ) {
318+ // For network errors, check connectivity
319+ if ( isNetworkError ( error ) ) {
320+ await this . checkAndReportConnectivity ( ) ;
321+ }
322+ return handleAxiosError ( error , operation ) ;
323+ }
324+
325+ if ( error instanceof TestingBotError ) {
326+ return error ;
327+ }
328+
329+ return new TestingBotError (
330+ `${ operation } : ${ error instanceof Error ? error . message : 'Unknown error' } ` ,
331+ { cause : error instanceof Error ? error : undefined } ,
332+ ) ;
333+ }
334+
269335 /**
270336 * Formats elapsed time in human-readable format
271337 */
0 commit comments