universal-parcel-scraper 0.5.0-main.321 → 0.5.0-main.322

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.
@@ -10,7 +10,7 @@ export declare class DPDChallengeError extends ChallengeError {
10
10
  /**
11
11
  * The guest API answered, but the answer proves nothing about the shipment
12
12
  * (unreachable, malformed, unauthenticated, or an HTTP status the guest flow
13
- * handles itself). The rendered page is allowed to recover from it.
13
+ * handles itself, except HTTP 503). The rendered page is allowed to recover from it.
14
14
  */
15
15
  export declare class DPDAPIError extends IndeterminateError {
16
16
  constructor(message: string, options?: CarrierErrorOptions);
@@ -2,7 +2,7 @@ import { setTimeout as delay } from 'node:timers/promises';
2
2
  import { randomBytes } from 'node:crypto';
3
3
  import { load } from 'cheerio';
4
4
  import { lookupBudget } from '../../core/adapter/index.js';
5
- import { BudgetExceededError, carrierErrorKind, ChallengeError, IndeterminateError, InvalidInputError, NotFoundError, SchemaError } from '../../core/errors/index.js';
5
+ import { BudgetExceededError, carrierErrorKind, ChallengeError, IndeterminateError, InvalidInputError, NotFoundError, SchemaError, UpstreamHttpError } from '../../core/errors/index.js';
6
6
  import { runSteps } from '../../core/runner/index.js';
7
7
  import { isoTime, explicitOffsetTime, zonedTime } from '../../core/time/index.js';
8
8
  import { TrawlClient, decodeText, fetchBounded, parseJsonBytes } from '../../core/transport/index.js';
@@ -19,7 +19,8 @@ import { API_LABELS, PROOF_OF_DELIVERY_SCAN, apiStage, apiStatus, scanStage, wor
19
19
  // `continueWithoutVerification=true`. A rejected postcode (HTTP 400) is
20
20
  // retried once without verification and reported as unverified rather than
21
21
  // failing the lookup.
22
- // - The consignee web page is the fallback when the guest API is inconclusive.
22
+ // - The consignee web page is the fallback when the guest API is inconclusive,
23
+ // except HTTP 503: the service is down, irrespective of the parcel number.
23
24
  // It sits behind Cloudflare, so it is fetched through the browser service's
24
25
  // legacy command API when one is configured and directly otherwise.
25
26
  const TRACKING_BASE = 'https://www.dpdgroup.com/ch/mydpd/my-parcels/incoming';
@@ -54,7 +55,7 @@ export class DPDChallengeError extends ChallengeError {
54
55
  /**
55
56
  * The guest API answered, but the answer proves nothing about the shipment
56
57
  * (unreachable, malformed, unauthenticated, or an HTTP status the guest flow
57
- * handles itself). The rendered page is allowed to recover from it.
58
+ * handles itself, except HTTP 503). The rendered page is allowed to recover from it.
58
59
  */
59
60
  export class DPDAPIError extends IndeterminateError {
60
61
  constructor(message, options) {
@@ -778,6 +779,10 @@ export class DPDTracker {
778
779
  catch (error) {
779
780
  throw new DPDAPIError('DPD guest API is unreachable', { cause: error });
780
781
  }
782
+ // A 503 describes DPD's availability, so the page must not turn it into
783
+ // an answer about the parcel or hold up the caller's other lookups.
784
+ if (result.response.status === 503)
785
+ throw new UpstreamHttpError('DPD guest API', 503);
781
786
  if (!result.response.ok)
782
787
  throw new DPDAPIHttpError(result.response.status);
783
788
  let payload;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "universal-parcel-scraper",
3
- "version": "0.5.0-main.321",
3
+ "version": "0.5.0-main.322",
4
4
  "description": "Self-hosted parcel tracking: carrier detection, dedicated scrapers and optional universal providers.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",