UNPKG

@hanivanrizky/nestjs-html-parser

Version:

A powerful NestJS HTML parsing service with XPath and CSS selector support, proxy configuration, random user agents, and rich response metadata including headers and status codes

230 lines โ€ข 8.93 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.testUrlWithRobustConfig = testUrlWithRobustConfig; exports.demonstrateSSLAndErrorHandling = demonstrateSSLAndErrorHandling; const html_parser_service_1 = require("../html-parser.service"); async function demonstrateSSLAndErrorHandling(verbose = false) { const parser = new html_parser_service_1.HtmlParserService(); console.log('๐Ÿ”ง SSL and Error Handling Demo'); console.log('='.repeat(50)); // Test URLs with different types of issues const testCases = [ { name: 'Valid HTTPS Site', url: 'https://httpbin.org/html', config: { verbose }, }, { name: 'Self-Signed Certificate', url: 'https://self-signed.badssl.com/', config: { rejectUnauthorized: false, retryOnErrors: { ssl: true }, verbose, }, }, { name: 'Expired Certificate', url: 'https://expired.badssl.com/', config: { ignoreSSLErrors: true, verbose, }, }, { name: 'Wrong Host Certificate', url: 'https://wrong.host.badssl.com/', config: { rejectUnauthorized: false, retryOnErrors: { ssl: true }, retries: 2, verbose, }, }, { name: 'Dead Domain (DNS Failure)', url: 'https://this-domain-definitely-does-not-exist-12345.com', config: { retries: 2, retryDelay: 1000, retryOnErrors: { dns: true }, timeout: 5000, verbose, }, }, { name: 'Connection Timeout', url: 'https://httpbin.org/delay/10', config: { timeout: 3000, retries: 2, retryOnErrors: { timeout: true }, verbose, }, }, { name: 'Robust Configuration (Handle Most Errors)', url: 'https://httpbin.org/status/503', // Service unavailable config: { rejectUnauthorized: false, ignoreSSLErrors: false, timeout: 10000, retries: 3, retryDelay: 2000, retryOnErrors: { ssl: true, timeout: true, dns: true, connectionRefused: true, }, verbose, }, }, ]; const results = []; for (const testCase of testCases) { console.log(`\n๐Ÿงช Testing: ${testCase.name}`); console.log(`๐Ÿ“ URL: ${testCase.url}`); if (verbose) { console.log(`๐Ÿ”ง Config:`, testCase.config); } try { const startTime = Date.now(); const response = await parser.fetchHtml(testCase.url, testCase.config); const duration = Date.now() - startTime; // Try to extract title const title = parser.extractSingle(response.data, '//title/text()', 'xpath', undefined, { verbose: false }); console.log(`โœ… Success! (${duration}ms)`); console.log(`๐Ÿ“Š Status: ${response.status} ${response.statusText}`); console.log(`๐Ÿ“„ Title: ${title || 'No title found'}`); console.log(`๐Ÿ“ Content length: ${response.data.length} characters`); results.push({ url: testCase.url, success: true, title: title || undefined, }); } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); // Extract error type from enhanced error message const errorTypeMatch = errorMessage.match(/Error type: (\w+)/); const errorType = errorTypeMatch ? errorTypeMatch[1] : 'unknown'; console.log(`โŒ Failed: ${errorType}`); console.log(`๐Ÿ” Error: ${errorMessage}`); results.push({ url: testCase.url, success: false, error: errorMessage, errorType, }); } } // Summary console.log('\n๐Ÿ“Š SUMMARY RESULTS'); console.log('='.repeat(40)); const successful = results.filter((r) => r.success); const failed = results.filter((r) => !r.success); console.log(`โœ… Successful: ${successful.length}/${results.length}`); console.log(`โŒ Failed: ${failed.length}/${results.length}`); if (successful.length > 0) { console.log('\n๐ŸŽฏ Successful Requests:'); successful.forEach((result, index) => { console.log(` ${index + 1}. ${result.title || 'No title'} - ${result.url}`); }); } if (failed.length > 0) { console.log('\n๐Ÿ’ฅ Failed Requests by Error Type:'); const errorGroups = failed.reduce((groups, result) => { const type = result.errorType || 'unknown'; if (!groups[type]) groups[type] = []; groups[type].push(result); return groups; }, {}); Object.entries(errorGroups).forEach(([errorType, errors]) => { console.log(`\n ๐Ÿ”ด ${errorType.toUpperCase()} (${errors.length})`); errors.forEach((error, index) => { console.log(` ${index + 1}. ${error.url}`); }); }); } // Recommendations console.log('\n๐Ÿ’ก RECOMMENDATIONS FOR COMMON ISSUES'); console.log('='.repeat(45)); console.log('๐Ÿ”’ SSL Certificate Issues:'); console.log(' - Use rejectUnauthorized: false for self-signed certificates'); console.log(' - Use ignoreSSLErrors: true for completely broken SSL (use with caution)'); console.log(' - Enable retryOnErrors.ssl: true for transient SSL issues'); console.log('\n๐Ÿ’€ Dead Domains:'); console.log(' - Enable retryOnErrors.dns: true for temporary DNS issues'); console.log(' - Reduce timeout for faster failure detection'); console.log(' - Use domain health checking before scraping'); console.log('\nโฑ๏ธ Timeout Issues:'); console.log(' - Increase timeout value for slow sites'); console.log(' - Enable retryOnErrors.timeout: true'); console.log(' - Use proxy rotation for better performance'); console.log('\n๐Ÿ›ก๏ธ Connection Issues:'); console.log(' - Enable retryOnErrors.connectionRefused: true'); console.log(' - Use different user agents to avoid blocking'); console.log(' - Implement proxy rotation for resilience'); } // Utility function to test a single URL with robust configuration async function testUrlWithRobustConfig(url, verbose = false) { const parser = new html_parser_service_1.HtmlParserService(); const robustConfig = { // SSL handling rejectUnauthorized: false, ignoreSSLErrors: false, // Timeouts and retries timeout: 15000, retries: 5, retryDelay: 2000, maxRedirects: 10, // Retry on all common error types retryOnErrors: { ssl: true, timeout: true, dns: true, connectionRefused: true, }, // User agent rotation useRandomUserAgent: true, // Additional headers headers: { Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate', 'Cache-Control': 'no-cache', Pragma: 'no-cache', }, verbose, }; try { const response = await parser.fetchHtml(url, robustConfig); const title = parser.extractSingle(response.data, '//title/text()'); return { url, success: true, title: title || undefined, }; } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); const errorTypeMatch = errorMessage.match(/Error type: (\w+)/); return { url, success: false, error: errorMessage, errorType: errorTypeMatch ? errorTypeMatch[1] : 'unknown', }; } } // Run the demonstration if this file is executed directly if (require.main === module) { // Check for verbose flag in command line arguments const verbose = process.argv.includes('--verbose') || process.argv.includes('-v'); demonstrateSSLAndErrorHandling(verbose) .then(() => console.log('\n๐Ÿ”ง SSL and error handling demo completed!')) .catch(console.error); } //# sourceMappingURL=ssl-and-dead-domains.js.map