crawlberg 1.11.1-aarch64-linux → 1.12.2-aarch64-linux

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  // This file is auto-generated by alef. DO NOT EDIT.
2
- // alef:hash:2ec1fdc93f72b06b0d045fd1f6b6288fad256babb9754b0e89759ebc3fd4b1f8
2
+ // alef:hash:5766b3fb05a187f88eec0ae0ee3c5e32d6bede7f1a3bc38b4305587073983bbd
3
3
  // Re-generate with: alef generate
4
4
  #![allow(dead_code, unused_imports, unused_variables)]
5
5
  #![allow(
@@ -843,6 +843,9 @@ pub struct BrowserConfig {
843
843
  session_affinity: bool,
844
844
  chrome_path: Option<String>,
845
845
  chrome_args: Vec<String>,
846
+ scroll_containers: bool,
847
+ dom_quiet_window: u64,
848
+ dom_quiet_cap: u64,
846
849
  }
847
850
 
848
851
  unsafe impl IntoValueFromNative for BrowserConfig {}
@@ -892,6 +895,9 @@ impl std::fmt::Debug for BrowserConfig {
892
895
  debug.field("session_affinity", &self.session_affinity);
893
896
  debug.field("chrome_path", &self.chrome_path);
894
897
  debug.field("chrome_args", &"<redacted>");
898
+ debug.field("scroll_containers", &self.scroll_containers);
899
+ debug.field("dom_quiet_window", &self.dom_quiet_window);
900
+ debug.field("dom_quiet_cap", &self.dom_quiet_cap);
895
901
  debug.finish()
896
902
  }
897
903
  }
@@ -1070,6 +1076,33 @@ impl BrowserConfig {
1070
1076
  })?,
1071
1077
  None => Default::default(),
1072
1078
  },
1079
+ scroll_containers: match kwargs.get(ruby.to_symbol("scroll_containers")) {
1080
+ Some(v) => bool::try_convert(v).map_err(|e| {
1081
+ magnus::Error::new(
1082
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1083
+ format!("invalid value for `scroll_containers`: {}", e),
1084
+ )
1085
+ })?,
1086
+ None => false,
1087
+ },
1088
+ dom_quiet_window: match kwargs.get(ruby.to_symbol("dom_quiet_window")) {
1089
+ Some(v) => u64::try_convert(v).map_err(|e| {
1090
+ magnus::Error::new(
1091
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1092
+ format!("invalid value for `dom_quiet_window`: {}", e),
1093
+ )
1094
+ })?,
1095
+ None => 150,
1096
+ },
1097
+ dom_quiet_cap: match kwargs.get(ruby.to_symbol("dom_quiet_cap")) {
1098
+ Some(v) => u64::try_convert(v).map_err(|e| {
1099
+ magnus::Error::new(
1100
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1101
+ format!("invalid value for `dom_quiet_cap`: {}", e),
1102
+ )
1103
+ })?,
1104
+ None => 4000,
1105
+ },
1073
1106
  })
1074
1107
  }
1075
1108
 
@@ -1140,6 +1173,18 @@ impl BrowserConfig {
1140
1173
  fn chrome_args(&self) -> Vec<String> {
1141
1174
  self.chrome_args.clone()
1142
1175
  }
1176
+
1177
+ fn scroll_containers(&self) -> bool {
1178
+ self.scroll_containers
1179
+ }
1180
+
1181
+ fn dom_quiet_window(&self) -> u64 {
1182
+ self.dom_quiet_window.clone()
1183
+ }
1184
+
1185
+ fn dom_quiet_cap(&self) -> u64 {
1186
+ self.dom_quiet_cap.clone()
1187
+ }
1143
1188
  }
1144
1189
 
1145
1190
  #[derive(Clone, Debug, serde::Serialize)]
@@ -1444,6 +1489,10 @@ pub struct ContentConfig {
1444
1489
  compact_tables: bool,
1445
1490
  keep_inline_images_in: Vec<String>,
1446
1491
  keep_hidden: bool,
1492
+ expand_abbreviations: bool,
1493
+ escape_misc: bool,
1494
+ escape_asterisks: bool,
1495
+ include_icon_labels: bool,
1447
1496
  }
1448
1497
 
1449
1498
  unsafe impl IntoValueFromNative for ContentConfig {}
@@ -1675,6 +1724,42 @@ impl ContentConfig {
1675
1724
  })?,
1676
1725
  None => false,
1677
1726
  },
1727
+ expand_abbreviations: match kwargs.get(ruby.to_symbol("expand_abbreviations")) {
1728
+ Some(v) => bool::try_convert(v).map_err(|e| {
1729
+ magnus::Error::new(
1730
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1731
+ format!("invalid value for `expand_abbreviations`: {}", e),
1732
+ )
1733
+ })?,
1734
+ None => true,
1735
+ },
1736
+ escape_misc: match kwargs.get(ruby.to_symbol("escape_misc")) {
1737
+ Some(v) => bool::try_convert(v).map_err(|e| {
1738
+ magnus::Error::new(
1739
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1740
+ format!("invalid value for `escape_misc`: {}", e),
1741
+ )
1742
+ })?,
1743
+ None => false,
1744
+ },
1745
+ escape_asterisks: match kwargs.get(ruby.to_symbol("escape_asterisks")) {
1746
+ Some(v) => bool::try_convert(v).map_err(|e| {
1747
+ magnus::Error::new(
1748
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1749
+ format!("invalid value for `escape_asterisks`: {}", e),
1750
+ )
1751
+ })?,
1752
+ None => false,
1753
+ },
1754
+ include_icon_labels: match kwargs.get(ruby.to_symbol("include_icon_labels")) {
1755
+ Some(v) => bool::try_convert(v).map_err(|e| {
1756
+ magnus::Error::new(
1757
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1758
+ format!("invalid value for `include_icon_labels`: {}", e),
1759
+ )
1760
+ })?,
1761
+ None => true,
1762
+ },
1678
1763
  })
1679
1764
  }
1680
1765
 
@@ -1757,6 +1842,22 @@ impl ContentConfig {
1757
1842
  fn keep_hidden(&self) -> bool {
1758
1843
  self.keep_hidden
1759
1844
  }
1845
+
1846
+ fn expand_abbreviations(&self) -> bool {
1847
+ self.expand_abbreviations
1848
+ }
1849
+
1850
+ fn escape_misc(&self) -> bool {
1851
+ self.escape_misc
1852
+ }
1853
+
1854
+ fn escape_asterisks(&self) -> bool {
1855
+ self.escape_asterisks
1856
+ }
1857
+
1858
+ fn include_icon_labels(&self) -> bool {
1859
+ self.include_icon_labels
1860
+ }
1760
1861
  }
1761
1862
 
1762
1863
  #[derive(Clone, serde::Serialize, serde::Deserialize)]
@@ -1936,6 +2037,8 @@ pub struct CrawlConfig {
1936
2037
  save_browser_profile: bool,
1937
2038
  ssrf: SsrfPolicy,
1938
2039
  ssrf_deny_private_explicit: Option<bool>,
2040
+ danger_accept_invalid_certs: bool,
2041
+ subdomain_header_allowlist: Vec<String>,
1939
2042
  }
1940
2043
 
1941
2044
  unsafe impl IntoValueFromNative for CrawlConfig {}
@@ -2023,6 +2126,8 @@ impl std::fmt::Debug for CrawlConfig {
2023
2126
  debug.field("save_browser_profile", &self.save_browser_profile);
2024
2127
  debug.field("ssrf", &self.ssrf);
2025
2128
  debug.field("ssrf_deny_private_explicit", &self.ssrf_deny_private_explicit);
2129
+ debug.field("danger_accept_invalid_certs", &self.danger_accept_invalid_certs);
2130
+ debug.field("subdomain_header_allowlist", &self.subdomain_header_allowlist);
2026
2131
  debug.finish()
2027
2132
  }
2028
2133
  }
@@ -2549,6 +2654,24 @@ impl CrawlConfig {
2549
2654
  })?),
2550
2655
  None => None,
2551
2656
  },
2657
+ danger_accept_invalid_certs: match kwargs.get(ruby.to_symbol("danger_accept_invalid_certs")) {
2658
+ Some(v) => bool::try_convert(v).map_err(|e| {
2659
+ magnus::Error::new(
2660
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2661
+ format!("invalid value for `danger_accept_invalid_certs`: {}", e),
2662
+ )
2663
+ })?,
2664
+ None => false,
2665
+ },
2666
+ subdomain_header_allowlist: match kwargs.get(ruby.to_symbol("subdomain_header_allowlist")) {
2667
+ Some(v) => <Vec<String>>::try_convert(v).map_err(|e| {
2668
+ magnus::Error::new(
2669
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2670
+ format!("invalid value for `subdomain_header_allowlist`: {}", e),
2671
+ )
2672
+ })?,
2673
+ None => Default::default(),
2674
+ },
2552
2675
  })
2553
2676
  }
2554
2677
 
@@ -2772,6 +2895,14 @@ impl CrawlConfig {
2772
2895
  self.ssrf_deny_private_explicit
2773
2896
  }
2774
2897
 
2898
+ fn danger_accept_invalid_certs(&self) -> bool {
2899
+ self.danger_accept_invalid_certs
2900
+ }
2901
+
2902
+ fn subdomain_header_allowlist(&self) -> Vec<String> {
2903
+ self.subdomain_header_allowlist.clone()
2904
+ }
2905
+
2775
2906
  fn validate(&self) -> Result<(), Error> {
2776
2907
  #[allow(clippy::needless_update)]
2777
2908
  let core_self = crawlberg::CrawlConfig {
@@ -2890,14 +3021,13 @@ impl CrawlConfig {
2890
3021
 
2891
3022
  ssrf_deny_private_explicit: self.ssrf_deny_private_explicit,
2892
3023
 
3024
+ danger_accept_invalid_certs: self.danger_accept_invalid_certs,
3025
+
3026
+ subdomain_header_allowlist: self.subdomain_header_allowlist.clone(),
3027
+
2893
3028
  ..Default::default()
2894
3029
  };
2895
- let result = core_self.validate().map_err(|e| {
2896
- magnus::Error::new(
2897
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
2898
- e.to_string(),
2899
- )
2900
- })?;
3030
+ let result = core_self.validate().map_err(alef_magnus_err)?;
2901
3031
  Ok(result)
2902
3032
  }
2903
3033
  }
@@ -2948,12 +3078,7 @@ impl CrawlEngineHandle {
2948
3078
  );
2949
3079
  let stream = runtime
2950
3080
  .block_on(async { inner.crawl_stream(core_req).await })
2951
- .map_err(|e| {
2952
- magnus::Error::new(
2953
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
2954
- e.to_string(),
2955
- )
2956
- })?;
3081
+ .map_err(alef_magnus_err)?;
2957
3082
  let iterator = CrawlStreamIterator {
2958
3083
  inner: Arc::new(tokio::sync::Mutex::new(Some(stream))),
2959
3084
  runtime,
@@ -2993,12 +3118,7 @@ impl CrawlEngineHandle {
2993
3118
  );
2994
3119
  let stream = runtime
2995
3120
  .block_on(async { inner.batch_crawl_stream(core_req).await })
2996
- .map_err(|e| {
2997
- magnus::Error::new(
2998
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
2999
- e.to_string(),
3000
- )
3001
- })?;
3121
+ .map_err(alef_magnus_err)?;
3002
3122
  let iterator = BatchCrawlStreamIterator {
3003
3123
  inner: Arc::new(tokio::sync::Mutex::new(Some(stream))),
3004
3124
  runtime,
@@ -3454,7 +3574,7 @@ impl CrawlPageResult {
3454
3574
  }
3455
3575
  }
3456
3576
 
3457
- #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
3577
+ #[derive(Clone, Debug, serde::Serialize)]
3458
3578
  #[serde(default)]
3459
3579
  #[magnus::wrap(class = "Crawlberg::CrawlResult")]
3460
3580
  pub struct CrawlResult {
@@ -3466,6 +3586,7 @@ pub struct CrawlResult {
3466
3586
  cookies: Vec<CookieInfo>,
3467
3587
  stayed_on_domain: bool,
3468
3588
  browser_used: bool,
3589
+ waf_block: Option<WafBlockDetails>,
3469
3590
  }
3470
3591
 
3471
3592
  unsafe impl IntoValueFromNative for CrawlResult {}
@@ -3495,6 +3616,14 @@ impl magnus::TryConvert for CrawlResult {
3495
3616
  }
3496
3617
 
3497
3618
  unsafe impl TryConvertOwned for CrawlResult {}
3619
+ impl<'de> serde::Deserialize<'de> for CrawlResult {
3620
+ fn deserialize<D>(deserializer: D) -> ::core::result::Result<Self, D::Error>
3621
+ where
3622
+ D: serde::Deserializer<'de>,
3623
+ {
3624
+ <crawlberg::CrawlResult as serde::Deserialize>::deserialize(deserializer).map(Into::into)
3625
+ }
3626
+ }
3498
3627
 
3499
3628
  impl Default for CrawlResult {
3500
3629
  fn default() -> Self {
@@ -3581,6 +3710,15 @@ impl CrawlResult {
3581
3710
  })?,
3582
3711
  None => Default::default(),
3583
3712
  },
3713
+ waf_block: match kwargs.get(ruby.to_symbol("waf_block")).filter(|v| !v.is_nil()) {
3714
+ Some(v) => Some(WafBlockDetails::try_convert(v).map_err(|e| {
3715
+ magnus::Error::new(
3716
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3717
+ format!("invalid value for `waf_block`: {}", e),
3718
+ )
3719
+ })?),
3720
+ None => None,
3721
+ },
3584
3722
  })
3585
3723
  }
3586
3724
 
@@ -3616,6 +3754,10 @@ impl CrawlResult {
3616
3754
  self.browser_used
3617
3755
  }
3618
3756
 
3757
+ fn waf_block(&self) -> Option<WafBlockDetails> {
3758
+ self.waf_block.clone()
3759
+ }
3760
+
3619
3761
  fn unique_normalized_urls(&self) -> usize {
3620
3762
  #[allow(clippy::needless_update)]
3621
3763
  let core_self = crawlberg::CrawlResult {
@@ -3635,6 +3777,8 @@ impl CrawlResult {
3635
3777
 
3636
3778
  browser_used: self.browser_used,
3637
3779
 
3780
+ waf_block: self.waf_block.clone().map(Into::into),
3781
+
3638
3782
  ..Default::default()
3639
3783
  };
3640
3784
  core_self.unique_normalized_urls()
@@ -6845,6 +6989,99 @@ impl SsrfPolicy {
6845
6989
  }
6846
6990
  }
6847
6991
 
6992
+ #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
6993
+ #[serde(default)]
6994
+ #[magnus::wrap(class = "Crawlberg::WafBlockDetails")]
6995
+ pub struct WafBlockDetails {
6996
+ vendor: String,
6997
+ status: Option<u16>,
6998
+ body_prefix: Option<String>,
6999
+ }
7000
+
7001
+ unsafe impl IntoValueFromNative for WafBlockDetails {}
7002
+
7003
+ impl magnus::TryConvert for WafBlockDetails {
7004
+ fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
7005
+ if let Ok(r) = <&WafBlockDetails as magnus::TryConvert>::try_convert(val) {
7006
+ return Ok(r.clone());
7007
+ }
7008
+ let json_str: String = if let Ok(s) = <String as magnus::TryConvert>::try_convert(val) {
7009
+ s
7010
+ } else {
7011
+ val.funcall::<_, _, String>("to_json", ()).map_err(|e| {
7012
+ magnus::Error::new(
7013
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
7014
+ format!("no implicit conversion into WafBlockDetails: {}", e),
7015
+ )
7016
+ })?
7017
+ };
7018
+ serde_json::from_str::<WafBlockDetails>(&json_str).map_err(|e| {
7019
+ magnus::Error::new(
7020
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
7021
+ format!("failed to deserialize WafBlockDetails: {}", e),
7022
+ )
7023
+ })
7024
+ }
7025
+ }
7026
+
7027
+ unsafe impl TryConvertOwned for WafBlockDetails {}
7028
+
7029
+ impl Default for WafBlockDetails {
7030
+ fn default() -> Self {
7031
+ crawlberg::WafBlockDetails::default().into()
7032
+ }
7033
+ }
7034
+
7035
+ impl WafBlockDetails {
7036
+ fn new(args: &[magnus::Value]) -> Result<Self, magnus::Error> {
7037
+ let ruby = unsafe { magnus::Ruby::get_unchecked() };
7038
+ let args = magnus::scan_args::scan_args::<(), (Option<magnus::RHash>,), (), (), (), ()>(args)?;
7039
+ let (kwargs_opt,) = args.optional;
7040
+ let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
7041
+ Ok(Self {
7042
+ vendor: match kwargs.get(ruby.to_symbol("vendor")) {
7043
+ Some(v) => String::try_convert(v).map_err(|e| {
7044
+ magnus::Error::new(
7045
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
7046
+ format!("invalid value for `vendor`: {}", e),
7047
+ )
7048
+ })?,
7049
+ None => Default::default(),
7050
+ },
7051
+ status: match kwargs.get(ruby.to_symbol("status")).filter(|v| !v.is_nil()) {
7052
+ Some(v) => Some(u16::try_convert(v).map_err(|e| {
7053
+ magnus::Error::new(
7054
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
7055
+ format!("invalid value for `status`: {}", e),
7056
+ )
7057
+ })?),
7058
+ None => None,
7059
+ },
7060
+ body_prefix: match kwargs.get(ruby.to_symbol("body_prefix")).filter(|v| !v.is_nil()) {
7061
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
7062
+ magnus::Error::new(
7063
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
7064
+ format!("invalid value for `body_prefix`: {}", e),
7065
+ )
7066
+ })?),
7067
+ None => None,
7068
+ },
7069
+ })
7070
+ }
7071
+
7072
+ fn vendor(&self) -> String {
7073
+ self.vendor.clone()
7074
+ }
7075
+
7076
+ fn status(&self) -> Option<u16> {
7077
+ self.status
7078
+ }
7079
+
7080
+ fn body_prefix(&self) -> Option<String> {
7081
+ self.body_prefix.clone()
7082
+ }
7083
+ }
7084
+
6848
7085
  #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, serde::Serialize, serde::Deserialize)]
6849
7086
  #[serde(rename_all = "snake_case")]
6850
7087
  pub enum AssetCategory {
@@ -7612,6 +7849,8 @@ pub enum PageAction {
7612
7849
  selector: Option<String>,
7613
7850
  },
7614
7851
  Screenshot {
7852
+ #[serde(rename = "fullPage")]
7853
+ #[serde(alias = "full_page")]
7615
7854
  full_page: Option<bool>,
7616
7855
  },
7617
7856
  #[serde(rename = "executeJs")]
@@ -7735,11 +7974,11 @@ fn batch_crawl(engine: CrawlEngineHandle, urls: Vec<String>) -> Result<BatchCraw
7735
7974
  .enable_all()
7736
7975
  .build()
7737
7976
  .map_err(|e| e.to_string())?;
7738
- rt.block_on(async { crawlberg::batch_crawl(&engine.inner, urls).await })
7739
- .map_err(|e| e.to_string())
7977
+ Ok(rt.block_on(async { crawlberg::batch_crawl(&engine.inner, urls).await }))
7740
7978
  });
7741
7979
  let result = async_result
7742
7980
  .map_err(|message| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_runtime_error(), message))?;
7981
+ let result = result.map_err(alef_magnus_err)?;
7743
7982
  Ok(result.into())
7744
7983
  }
7745
7984
 
@@ -7749,11 +7988,11 @@ fn batch_crawl_async(engine: CrawlEngineHandle, urls: Vec<String>) -> Result<Bat
7749
7988
  .enable_all()
7750
7989
  .build()
7751
7990
  .map_err(|e| e.to_string())?;
7752
- rt.block_on(async { crawlberg::batch_crawl(&engine.inner, urls).await })
7753
- .map_err(|e| e.to_string())
7991
+ Ok(rt.block_on(async { crawlberg::batch_crawl(&engine.inner, urls).await }))
7754
7992
  });
7755
7993
  let result = async_result
7756
7994
  .map_err(|message| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_runtime_error(), message))?;
7995
+ let result = result.map_err(alef_magnus_err)?;
7757
7996
  Ok(result.into())
7758
7997
  }
7759
7998
 
@@ -7763,11 +8002,11 @@ fn batch_scrape(engine: CrawlEngineHandle, urls: Vec<String>) -> Result<BatchScr
7763
8002
  .enable_all()
7764
8003
  .build()
7765
8004
  .map_err(|e| e.to_string())?;
7766
- rt.block_on(async { crawlberg::batch_scrape(&engine.inner, urls).await })
7767
- .map_err(|e| e.to_string())
8005
+ Ok(rt.block_on(async { crawlberg::batch_scrape(&engine.inner, urls).await }))
7768
8006
  });
7769
8007
  let result = async_result
7770
8008
  .map_err(|message| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_runtime_error(), message))?;
8009
+ let result = result.map_err(alef_magnus_err)?;
7771
8010
  Ok(result.into())
7772
8011
  }
7773
8012
 
@@ -7777,11 +8016,11 @@ fn batch_scrape_async(engine: CrawlEngineHandle, urls: Vec<String>) -> Result<Ba
7777
8016
  .enable_all()
7778
8017
  .build()
7779
8018
  .map_err(|e| e.to_string())?;
7780
- rt.block_on(async { crawlberg::batch_scrape(&engine.inner, urls).await })
7781
- .map_err(|e| e.to_string())
8019
+ Ok(rt.block_on(async { crawlberg::batch_scrape(&engine.inner, urls).await }))
7782
8020
  });
7783
8021
  let result = async_result
7784
8022
  .map_err(|message| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_runtime_error(), message))?;
8023
+ let result = result.map_err(alef_magnus_err)?;
7785
8024
  Ok(result.into())
7786
8025
  }
7787
8026
 
@@ -7791,11 +8030,11 @@ fn crawl(engine: CrawlEngineHandle, url: String) -> Result<CrawlResult, Error> {
7791
8030
  .enable_all()
7792
8031
  .build()
7793
8032
  .map_err(|e| e.to_string())?;
7794
- rt.block_on(async { crawlberg::crawl(&engine.inner, &url).await })
7795
- .map_err(|e| e.to_string())
8033
+ Ok(rt.block_on(async { crawlberg::crawl(&engine.inner, &url).await }))
7796
8034
  });
7797
8035
  let result = async_result
7798
8036
  .map_err(|message| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_runtime_error(), message))?;
8037
+ let result = result.map_err(alef_magnus_err)?;
7799
8038
  Ok(result.into())
7800
8039
  }
7801
8040
 
@@ -7805,11 +8044,11 @@ fn crawl_async(engine: CrawlEngineHandle, url: String) -> Result<CrawlResult, Er
7805
8044
  .enable_all()
7806
8045
  .build()
7807
8046
  .map_err(|e| e.to_string())?;
7808
- rt.block_on(async { crawlberg::crawl(&engine.inner, &url).await })
7809
- .map_err(|e| e.to_string())
8047
+ Ok(rt.block_on(async { crawlberg::crawl(&engine.inner, &url).await }))
7810
8048
  });
7811
8049
  let result = async_result
7812
8050
  .map_err(|message| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_runtime_error(), message))?;
8051
+ let result = result.map_err(alef_magnus_err)?;
7813
8052
  Ok(result.into())
7814
8053
  }
7815
8054
 
@@ -7826,12 +8065,7 @@ fn create_engine(args: &[magnus::Value]) -> Result<CrawlEngineHandle, Error> {
7826
8065
  }
7827
8066
  _ => None,
7828
8067
  };
7829
- let result = crawlberg::create_engine(config.map(Into::into)).map_err(|e| {
7830
- magnus::Error::new(
7831
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
7832
- e.to_string(),
7833
- )
7834
- })?;
8068
+ let result = crawlberg::create_engine(config.map(Into::into)).map_err(alef_magnus_err)?;
7835
8069
  Ok(CrawlEngineHandle {
7836
8070
  inner: Arc::new(result),
7837
8071
  })
@@ -7848,11 +8082,11 @@ fn interact(engine: CrawlEngineHandle, url: String, actions: Vec<PageAction>) ->
7848
8082
  .enable_all()
7849
8083
  .build()
7850
8084
  .map_err(|e| e.to_string())?;
7851
- rt.block_on(async { crawlberg::interact(&engine.inner, &url, actions_core).await })
7852
- .map_err(|e| e.to_string())
8085
+ Ok(rt.block_on(async { crawlberg::interact(&engine.inner, &url, actions_core).await }))
7853
8086
  });
7854
8087
  let result = async_result
7855
8088
  .map_err(|message| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_runtime_error(), message))?;
8089
+ let result = result.map_err(alef_magnus_err)?;
7856
8090
  Ok(result.into())
7857
8091
  }
7858
8092
 
@@ -7867,11 +8101,11 @@ fn interact_async(
7867
8101
  .enable_all()
7868
8102
  .build()
7869
8103
  .map_err(|e| e.to_string())?;
7870
- rt.block_on(async { crawlberg::interact(&engine.inner, &url, actions_core).await })
7871
- .map_err(|e| e.to_string())
8104
+ Ok(rt.block_on(async { crawlberg::interact(&engine.inner, &url, actions_core).await }))
7872
8105
  });
7873
8106
  let result = async_result
7874
8107
  .map_err(|message| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_runtime_error(), message))?;
8108
+ let result = result.map_err(alef_magnus_err)?;
7875
8109
  Ok(result.into())
7876
8110
  }
7877
8111
 
@@ -7881,11 +8115,11 @@ fn map_urls(engine: CrawlEngineHandle, url: String) -> Result<MapResult, Error>
7881
8115
  .enable_all()
7882
8116
  .build()
7883
8117
  .map_err(|e| e.to_string())?;
7884
- rt.block_on(async { crawlberg::map_urls(&engine.inner, &url).await })
7885
- .map_err(|e| e.to_string())
8118
+ Ok(rt.block_on(async { crawlberg::map_urls(&engine.inner, &url).await }))
7886
8119
  });
7887
8120
  let result = async_result
7888
8121
  .map_err(|message| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_runtime_error(), message))?;
8122
+ let result = result.map_err(alef_magnus_err)?;
7889
8123
  Ok(result.into())
7890
8124
  }
7891
8125
 
@@ -7895,11 +8129,11 @@ fn map_urls_async(engine: CrawlEngineHandle, url: String) -> Result<MapResult, E
7895
8129
  .enable_all()
7896
8130
  .build()
7897
8131
  .map_err(|e| e.to_string())?;
7898
- rt.block_on(async { crawlberg::map_urls(&engine.inner, &url).await })
7899
- .map_err(|e| e.to_string())
8132
+ Ok(rt.block_on(async { crawlberg::map_urls(&engine.inner, &url).await }))
7900
8133
  });
7901
8134
  let result = async_result
7902
8135
  .map_err(|message| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_runtime_error(), message))?;
8136
+ let result = result.map_err(alef_magnus_err)?;
7903
8137
  Ok(result.into())
7904
8138
  }
7905
8139
 
@@ -7909,11 +8143,11 @@ fn scrape(engine: CrawlEngineHandle, url: String) -> Result<ScrapeResult, Error>
7909
8143
  .enable_all()
7910
8144
  .build()
7911
8145
  .map_err(|e| e.to_string())?;
7912
- rt.block_on(async { crawlberg::scrape(&engine.inner, &url).await })
7913
- .map_err(|e| e.to_string())
8146
+ Ok(rt.block_on(async { crawlberg::scrape(&engine.inner, &url).await }))
7914
8147
  });
7915
8148
  let result = async_result
7916
8149
  .map_err(|message| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_runtime_error(), message))?;
8150
+ let result = result.map_err(alef_magnus_err)?;
7917
8151
  Ok(result.into())
7918
8152
  }
7919
8153
 
@@ -7923,11 +8157,11 @@ fn scrape_async(engine: CrawlEngineHandle, url: String) -> Result<ScrapeResult,
7923
8157
  .enable_all()
7924
8158
  .build()
7925
8159
  .map_err(|e| e.to_string())?;
7926
- rt.block_on(async { crawlberg::scrape(&engine.inner, &url).await })
7927
- .map_err(|e| e.to_string())
8160
+ Ok(rt.block_on(async { crawlberg::scrape(&engine.inner, &url).await }))
7928
8161
  });
7929
8162
  let result = async_result
7930
8163
  .map_err(|message| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_runtime_error(), message))?;
8164
+ let result = result.map_err(alef_magnus_err)?;
7931
8165
  Ok(result.into())
7932
8166
  }
7933
8167
 
@@ -8136,6 +8370,9 @@ impl From<BrowserConfig> for crawlberg::BrowserConfig {
8136
8370
  session_affinity: val.session_affinity,
8137
8371
  chrome_path: val.chrome_path.map(Into::into),
8138
8372
  chrome_args: val.chrome_args.into_iter().collect(),
8373
+ scroll_containers: val.scroll_containers,
8374
+ dom_quiet_window: std::time::Duration::from_millis(val.dom_quiet_window),
8375
+ dom_quiet_cap: std::time::Duration::from_millis(val.dom_quiet_cap),
8139
8376
  ..Default::default()
8140
8377
  }
8141
8378
  }
@@ -8162,6 +8399,9 @@ impl From<crawlberg::BrowserConfig> for BrowserConfig {
8162
8399
  session_affinity: val.session_affinity,
8163
8400
  chrome_path: val.chrome_path.map(|p| p.to_string_lossy().to_string()),
8164
8401
  chrome_args: val.chrome_args.into_iter().collect(),
8402
+ scroll_containers: val.scroll_containers,
8403
+ dom_quiet_window: val.dom_quiet_window.as_millis() as u64,
8404
+ dom_quiet_cap: val.dom_quiet_cap.as_millis() as u64,
8165
8405
  }
8166
8406
  }
8167
8407
  }
@@ -8258,6 +8498,10 @@ impl From<ContentConfig> for crawlberg::ContentConfig {
8258
8498
  compact_tables: val.compact_tables,
8259
8499
  keep_inline_images_in: val.keep_inline_images_in.into_iter().collect(),
8260
8500
  keep_hidden: val.keep_hidden,
8501
+ expand_abbreviations: val.expand_abbreviations,
8502
+ escape_misc: val.escape_misc,
8503
+ escape_asterisks: val.escape_asterisks,
8504
+ include_icon_labels: val.include_icon_labels,
8261
8505
  ..Default::default()
8262
8506
  }
8263
8507
  }
@@ -8286,6 +8530,10 @@ impl From<crawlberg::ContentConfig> for ContentConfig {
8286
8530
  compact_tables: val.compact_tables,
8287
8531
  keep_inline_images_in: val.keep_inline_images_in.into_iter().collect(),
8288
8532
  keep_hidden: val.keep_hidden,
8533
+ expand_abbreviations: val.expand_abbreviations,
8534
+ escape_misc: val.escape_misc,
8535
+ escape_asterisks: val.escape_asterisks,
8536
+ include_icon_labels: val.include_icon_labels,
8289
8537
  }
8290
8538
  }
8291
8539
  }
@@ -8379,6 +8627,8 @@ impl From<CrawlConfig> for crawlberg::CrawlConfig {
8379
8627
  save_browser_profile: val.save_browser_profile,
8380
8628
  ssrf: val.ssrf.into(),
8381
8629
  ssrf_deny_private_explicit: val.ssrf_deny_private_explicit,
8630
+ danger_accept_invalid_certs: val.danger_accept_invalid_certs,
8631
+ subdomain_header_allowlist: val.subdomain_header_allowlist.into_iter().collect(),
8382
8632
  ..Default::default()
8383
8633
  }
8384
8634
  }
@@ -8447,6 +8697,8 @@ impl From<crawlberg::CrawlConfig> for CrawlConfig {
8447
8697
  save_browser_profile: val.save_browser_profile,
8448
8698
  ssrf: val.ssrf.into(),
8449
8699
  ssrf_deny_private_explicit: val.ssrf_deny_private_explicit,
8700
+ danger_accept_invalid_certs: val.danger_accept_invalid_certs,
8701
+ subdomain_header_allowlist: val.subdomain_header_allowlist.into_iter().collect(),
8450
8702
  }
8451
8703
  }
8452
8704
  }
@@ -8536,6 +8788,7 @@ impl From<CrawlResult> for crawlberg::CrawlResult {
8536
8788
  cookies: val.cookies.into_iter().map(Into::into).collect(),
8537
8789
  stayed_on_domain: val.stayed_on_domain,
8538
8790
  browser_used: val.browser_used,
8791
+ waf_block: val.waf_block.map(Into::into),
8539
8792
  ..Default::default()
8540
8793
  }
8541
8794
  }
@@ -8553,6 +8806,7 @@ impl From<crawlberg::CrawlResult> for CrawlResult {
8553
8806
  cookies: val.cookies.into_iter().map(Into::into).collect(),
8554
8807
  stayed_on_domain: val.stayed_on_domain,
8555
8808
  browser_used: val.browser_used,
8809
+ waf_block: val.waf_block.map(Into::into),
8556
8810
  }
8557
8811
  }
8558
8812
  }
@@ -9214,6 +9468,29 @@ impl From<crawlberg::SsrfPolicy> for SsrfPolicy {
9214
9468
  }
9215
9469
  }
9216
9470
 
9471
+ #[allow(clippy::needless_update)]
9472
+ impl From<WafBlockDetails> for crawlberg::WafBlockDetails {
9473
+ fn from(val: WafBlockDetails) -> Self {
9474
+ Self {
9475
+ vendor: val.vendor,
9476
+ status: val.status,
9477
+ body_prefix: val.body_prefix,
9478
+ ..Default::default()
9479
+ }
9480
+ }
9481
+ }
9482
+
9483
+ #[allow(clippy::redundant_closure)]
9484
+ impl From<crawlberg::WafBlockDetails> for WafBlockDetails {
9485
+ fn from(val: crawlberg::WafBlockDetails) -> Self {
9486
+ Self {
9487
+ vendor: val.vendor.to_string(),
9488
+ status: val.status,
9489
+ body_prefix: val.body_prefix.map(|v| v.to_string()),
9490
+ }
9491
+ }
9492
+ }
9493
+
9217
9494
  impl From<AssetCategory> for crawlberg::AssetCategory {
9218
9495
  fn from(val: AssetCategory) -> Self {
9219
9496
  match val {
@@ -9570,18 +9847,92 @@ impl From<crawlberg::ScrollDirection> for ScrollDirection {
9570
9847
  }
9571
9848
  }
9572
9849
 
9573
- /// Convert a `crawlberg::CrawlError` error to a Magnus runtime error.
9850
+ /// Convert the error a core call returned into the typed Ruby exception of its family. An error
9851
+ /// of a type with no converter becomes a `RuntimeError` with the message.
9852
+ #[allow(dead_code)]
9853
+ fn alef_magnus_err<E: std::fmt::Display + 'static>(e: E) -> magnus::Error {
9854
+ let message = e.to_string();
9855
+ #[allow(unused_variables)]
9856
+ let any: Box<dyn std::any::Any> = Box::new(e);
9857
+ let any = match any.downcast::<crawlberg::CrawlError>() {
9858
+ Ok(typed) => return crawl_error_to_magnus_err(*typed),
9859
+ Err(any) => any,
9860
+ };
9861
+ let any = match any.downcast::<crawlberg::SsrfError>() {
9862
+ Ok(typed) => return ssrf_error_to_magnus_err(*typed),
9863
+ Err(any) => any,
9864
+ };
9865
+ let _ = any;
9866
+ magnus::Error::new(
9867
+ unsafe { magnus::Ruby::get_unchecked() }.exception_runtime_error(),
9868
+ message,
9869
+ )
9870
+ }
9871
+
9872
+ /// Convert a `crawlberg::CrawlError` error to a typed Ruby exception.
9574
9873
  #[allow(dead_code)]
9575
9874
  fn crawl_error_to_magnus_err(e: crawlberg::CrawlError) -> magnus::Error {
9576
- let msg = e.to_string();
9577
- magnus::Error::new(unsafe { magnus::Ruby::get_unchecked() }.exception_runtime_error(), msg)
9875
+ use magnus::prelude::*;
9876
+ let message = e.to_string();
9877
+ let ruby = unsafe { magnus::Ruby::get_unchecked() };
9878
+ #[allow(unreachable_patterns)]
9879
+ let class_name = match &e {
9880
+ crawlberg::CrawlError::NotFound { .. } => "NotFoundError",
9881
+ crawlberg::CrawlError::Unauthorized { .. } => "UnauthorizedError",
9882
+ crawlberg::CrawlError::Forbidden { .. } => "ForbiddenError",
9883
+ crawlberg::CrawlError::WafBlocked { .. } => "WafBlockedError",
9884
+ crawlberg::CrawlError::Timeout { .. } => "CrawlTimeoutError",
9885
+ crawlberg::CrawlError::RateLimited { .. } => "RateLimitedError",
9886
+ crawlberg::CrawlError::ServerError { .. } => "ServerError",
9887
+ crawlberg::CrawlError::BadGateway { .. } => "BadGatewayError",
9888
+ crawlberg::CrawlError::Gone { .. } => "GoneError",
9889
+ crawlberg::CrawlError::Connection { .. } => "CrawlConnectionError",
9890
+ crawlberg::CrawlError::Dns { .. } => "DnsError",
9891
+ crawlberg::CrawlError::Ssl { .. } => "SslError",
9892
+ crawlberg::CrawlError::DataLoss { .. } => "DataLossError",
9893
+ crawlberg::CrawlError::ConversionFailed { .. } => "ConversionFailedError",
9894
+ crawlberg::CrawlError::BrowserError { .. } => "BrowserError",
9895
+ crawlberg::CrawlError::BrowserTimeout { .. } => "BrowserTimeoutError",
9896
+ crawlberg::CrawlError::InvalidConfig { .. } => "InvalidConfigError",
9897
+ crawlberg::CrawlError::Unsupported { .. } => "UnsupportedError",
9898
+ crawlberg::CrawlError::TooManyRedirects { .. } => "TooManyRedirectsError",
9899
+ crawlberg::CrawlError::SsrfPolicyViolation { .. } => "SsrfPolicyViolationError",
9900
+ crawlberg::CrawlError::Other { .. } => "OtherError",
9901
+ _ => "CrawlError",
9902
+ };
9903
+ let build = || -> Result<magnus::Error, magnus::Error> {
9904
+ let module = ruby.define_module("Crawlberg")?;
9905
+ let class: magnus::ExceptionClass = module.const_get(class_name)?;
9906
+ let exception = class.new_instance((message.as_str(),))?;
9907
+ Ok(magnus::Error::from(exception))
9908
+ };
9909
+ build().unwrap_or_else(|_| magnus::Error::new(ruby.exception_runtime_error(), message))
9578
9910
  }
9579
9911
 
9580
- /// Convert a `crawlberg::SsrfError` error to a Magnus runtime error.
9912
+ /// Convert a `crawlberg::SsrfError` error to a typed Ruby exception.
9581
9913
  #[allow(dead_code)]
9582
9914
  fn ssrf_error_to_magnus_err(e: crawlberg::SsrfError) -> magnus::Error {
9583
- let msg = e.to_string();
9584
- magnus::Error::new(unsafe { magnus::Ruby::get_unchecked() }.exception_runtime_error(), msg)
9915
+ use magnus::prelude::*;
9916
+ let message = e.to_string();
9917
+ let ruby = unsafe { magnus::Ruby::get_unchecked() };
9918
+ #[allow(unreachable_patterns)]
9919
+ let class_name = match &e {
9920
+ crawlberg::SsrfError::DeniedByPolicy { .. } => "DeniedByPolicyError",
9921
+ crawlberg::SsrfError::NotOnAllowlist => "NotOnAllowlistError",
9922
+ crawlberg::SsrfError::InvalidCidr(..) => "InvalidCidrError",
9923
+ crawlberg::SsrfError::DnsResolutionFailed(..) => "DnsResolutionFailedError",
9924
+ crawlberg::SsrfError::InvalidUrl(..) => "InvalidUrlError",
9925
+ crawlberg::SsrfError::DisallowedScheme(..) => "DisallowedSchemeError",
9926
+ crawlberg::SsrfError::TooManyRedirects => "TooManyRedirectsError",
9927
+ _ => "SsrfError",
9928
+ };
9929
+ let build = || -> Result<magnus::Error, magnus::Error> {
9930
+ let module = ruby.define_module("Crawlberg")?;
9931
+ let class: magnus::ExceptionClass = module.const_get(class_name)?;
9932
+ let exception = class.new_instance((message.as_str(),))?;
9933
+ Ok(magnus::Error::from(exception))
9934
+ };
9935
+ build().unwrap_or_else(|_| magnus::Error::new(ruby.exception_runtime_error(), message))
9585
9936
  }
9586
9937
 
9587
9938
  #[derive(Clone)]
@@ -9629,7 +9980,7 @@ impl CrawlStreamIterator {
9629
9980
  let binding: CrawlEvent = chunk.into();
9630
9981
  Ok(binding.into_value_with(&ruby))
9631
9982
  }
9632
- Some(Err(e)) => Err(Error::new(ruby.exception_runtime_error(), e.to_string())),
9983
+ Some(Err(e)) => Err(alef_magnus_err(e)),
9633
9984
  None => {
9634
9985
  // Drop the stream to release any resources.
9635
9986
  let inner = self.inner.clone();
@@ -9711,7 +10062,7 @@ impl BatchCrawlStreamIterator {
9711
10062
  let binding: CrawlEvent = chunk.into();
9712
10063
  Ok(binding.into_value_with(&ruby))
9713
10064
  }
9714
- Some(Err(e)) => Err(Error::new(ruby.exception_runtime_error(), e.to_string())),
10065
+ Some(Err(e)) => Err(alef_magnus_err(e)),
9715
10066
  None => {
9716
10067
  // Drop the stream to release any resources.
9717
10068
  let inner = self.inner.clone();
@@ -9876,6 +10227,12 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
9876
10227
 
9877
10228
  class.define_method("chrome_args", method!(BrowserConfig::chrome_args, 0))?;
9878
10229
 
10230
+ class.define_method("scroll_containers", method!(BrowserConfig::scroll_containers, 0))?;
10231
+
10232
+ class.define_method("dom_quiet_window", method!(BrowserConfig::dom_quiet_window, 0))?;
10233
+
10234
+ class.define_method("dom_quiet_cap", method!(BrowserConfig::dom_quiet_cap, 0))?;
10235
+
9879
10236
  let class = module.define_class("BrowserExtras", ruby.class_object())?;
9880
10237
 
9881
10238
  class.define_singleton_method("new", function!(BrowserExtras::new, -1))?;
@@ -9956,6 +10313,14 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
9956
10313
 
9957
10314
  class.define_method("keep_hidden", method!(ContentConfig::keep_hidden, 0))?;
9958
10315
 
10316
+ class.define_method("expand_abbreviations", method!(ContentConfig::expand_abbreviations, 0))?;
10317
+
10318
+ class.define_method("escape_misc", method!(ContentConfig::escape_misc, 0))?;
10319
+
10320
+ class.define_method("escape_asterisks", method!(ContentConfig::escape_asterisks, 0))?;
10321
+
10322
+ class.define_method("include_icon_labels", method!(ContentConfig::include_icon_labels, 0))?;
10323
+
9959
10324
  let class = module.define_class("CookieInfo", ruby.class_object())?;
9960
10325
 
9961
10326
  class.define_singleton_method("new", function!(CookieInfo::new, -1))?;
@@ -10100,6 +10465,16 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
10100
10465
  method!(CrawlConfig::ssrf_deny_private_explicit, 0),
10101
10466
  )?;
10102
10467
 
10468
+ class.define_method(
10469
+ "danger_accept_invalid_certs",
10470
+ method!(CrawlConfig::danger_accept_invalid_certs, 0),
10471
+ )?;
10472
+
10473
+ class.define_method(
10474
+ "subdomain_header_allowlist",
10475
+ method!(CrawlConfig::subdomain_header_allowlist, 0),
10476
+ )?;
10477
+
10103
10478
  class.define_method("validate", method!(CrawlConfig::validate, 0))?;
10104
10479
 
10105
10480
  let class = module.define_class("CrawlEngineHandle", ruby.class_object())?;
@@ -10185,6 +10560,8 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
10185
10560
 
10186
10561
  class.define_method("browser_used", method!(CrawlResult::browser_used, 0))?;
10187
10562
 
10563
+ class.define_method("waf_block", method!(CrawlResult::waf_block, 0))?;
10564
+
10188
10565
  class.define_method(
10189
10566
  "unique_normalized_urls",
10190
10567
  method!(CrawlResult::unique_normalized_urls, 0),
@@ -10574,6 +10951,16 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
10574
10951
 
10575
10952
  class.define_method("scheme_allowlist", method!(SsrfPolicy::scheme_allowlist, 0))?;
10576
10953
 
10954
+ let class = module.define_class("WafBlockDetails", ruby.class_object())?;
10955
+
10956
+ class.define_singleton_method("new", function!(WafBlockDetails::new, -1))?;
10957
+
10958
+ class.define_method("vendor", method!(WafBlockDetails::vendor, 0))?;
10959
+
10960
+ class.define_method("status", method!(WafBlockDetails::status, 0))?;
10961
+
10962
+ class.define_method("body_prefix", method!(WafBlockDetails::body_prefix, 0))?;
10963
+
10577
10964
  let class = module.define_class("CrawlStreamIterator", ruby.class_object())?;
10578
10965
  class.define_method("next_chunk", method!(CrawlStreamIterator::next_chunk, 0))?;
10579
10966
  class.define_method("each", method!(CrawlStreamIterator::each, 0))?;
@@ -10603,5 +10990,35 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
10603
10990
 
10604
10991
  module.define_module_function("batch_crawl_stream", function!(batch_crawl_stream, 2))?;
10605
10992
 
10993
+ let crawl_error_class = module.define_error("CrawlError", ruby.exception_standard_error())?;
10994
+ let not_found_error_class = module.define_error("NotFoundError", crawl_error_class)?;
10995
+ let unauthorized_error_class = module.define_error("UnauthorizedError", crawl_error_class)?;
10996
+ let forbidden_error_class = module.define_error("ForbiddenError", crawl_error_class)?;
10997
+ let waf_blocked_error_class = module.define_error("WafBlockedError", crawl_error_class)?;
10998
+ let crawl_timeout_error_class = module.define_error("CrawlTimeoutError", crawl_error_class)?;
10999
+ let rate_limited_error_class = module.define_error("RateLimitedError", crawl_error_class)?;
11000
+ let server_error_class = module.define_error("ServerError", crawl_error_class)?;
11001
+ let bad_gateway_error_class = module.define_error("BadGatewayError", crawl_error_class)?;
11002
+ let gone_error_class = module.define_error("GoneError", crawl_error_class)?;
11003
+ let crawl_connection_error_class = module.define_error("CrawlConnectionError", crawl_error_class)?;
11004
+ let dns_error_class = module.define_error("DnsError", crawl_error_class)?;
11005
+ let ssl_error_class = module.define_error("SslError", crawl_error_class)?;
11006
+ let data_loss_error_class = module.define_error("DataLossError", crawl_error_class)?;
11007
+ let conversion_failed_error_class = module.define_error("ConversionFailedError", crawl_error_class)?;
11008
+ let browser_error_class = module.define_error("BrowserError", crawl_error_class)?;
11009
+ let browser_timeout_error_class = module.define_error("BrowserTimeoutError", crawl_error_class)?;
11010
+ let invalid_config_error_class = module.define_error("InvalidConfigError", crawl_error_class)?;
11011
+ let unsupported_error_class = module.define_error("UnsupportedError", crawl_error_class)?;
11012
+ let ssrf_policy_violation_error_class = module.define_error("SsrfPolicyViolationError", crawl_error_class)?;
11013
+ let other_error_class = module.define_error("OtherError", crawl_error_class)?;
11014
+ let ssrf_error_class = module.define_error("SsrfError", crawl_error_class)?;
11015
+ let denied_by_policy_error_class = module.define_error("DeniedByPolicyError", ssrf_error_class)?;
11016
+ let not_on_allowlist_error_class = module.define_error("NotOnAllowlistError", ssrf_error_class)?;
11017
+ let invalid_cidr_error_class = module.define_error("InvalidCidrError", ssrf_error_class)?;
11018
+ let dns_resolution_failed_error_class = module.define_error("DnsResolutionFailedError", ssrf_error_class)?;
11019
+ let invalid_url_error_class = module.define_error("InvalidUrlError", ssrf_error_class)?;
11020
+ let disallowed_scheme_error_class = module.define_error("DisallowedSchemeError", ssrf_error_class)?;
11021
+ let too_many_redirects_error_class = module.define_error("TooManyRedirectsError", ssrf_error_class)?;
11022
+
10606
11023
  Ok(())
10607
11024
  }