juspay/hyperswitch · warning

webhook event type should be derived

Error message

webhook event type should be derived

What it means

Test helper `event_type_for` in gocardless.rs calls `get_webhook_event_type(...).expect("webhook event type should be derived")`. The panic means Gocardless webhook parsing failed to derive an event type from the constructed request (body/action parsing returned Err).

Solutions

  1. Extend the connector's event-type mapping to cover the new GoCardless action/resource type
  2. Verify the test body fixture deserializes into the expected GoCardless webhook payload struct
  3. Change expect to a match on Err to surface the parse error message

Example fix

// before
.expect("webhook event type should be derived")
// after
.unwrap_or_else(|e| panic!("webhook event type should be derived: {e:?}"))
Defensive patterns

Strategy: try-catch

Validate before calling

let payload: GocardlessIncomingWebhook = serde_json::from_str(body).expect("fixture must deserialize");

Type guard

fn event_resolvable(body: &str) -> bool {
    serde_json::from_str::<GocardlessWebhookBody>(body).map(|p| p.action_type().is_some()).unwrap_or(false)
}

Try / catch

get_webhook_event_type(&request, None).unwrap_or_else(|e| panic!("webhook event type should be derived: {e:?}"))

Prevention

When it happens

Trigger: A GoCardless webhook body whose `action`/resource type is not handled (or malformed JSON) is passed to get_webhook_event_type, which returns Err and the expect panics.

Common situations: Adding a new GoCardless event action to tests before extending the connector's event-type mapping, or a body fixture that does not match the expected serde schema.

Understand the failure class

Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.

Related errors


AI-assisted analysis of juspay/hyperswitch@afd9284352 (2026-09-18). Data as JSON: /api/errors/f12ca650c7f3c3b8. Report an issue: GitHub.

Appendix: source

Thrown at crates/hyperswitch_connectors/src/connectors/gocardless.rs:990

            }]
        })
        .to_string()
        .into_bytes()
    }

    fn event_type_for(resource_type: &str, action: &str, link_key: &str) -> IncomingWebhookEvent {
        let body = webhook_body(resource_type, action, link_key);
        let headers = actix_web::http::header::HeaderMap::new();
        let request = IncomingWebhookRequestDetails {
            method: http::Method::POST,
            uri: http::Uri::from_static("/webhooks"),
            headers: &headers,
            body: &body,
            query_params: String::new(),
        };
        Gocardless::new()
            .get_webhook_event_type(&request, None)
            .expect("webhook event type should be derived")
    }

    #[test]
    fn refund_actions_shared_with_payments_map_to_refund_events() {
        assert_eq!(
            event_type_for("refunds", "failed", "refund"),
            IncomingWebhookEvent::RefundFailure
        );
        assert_eq!(
            event_type_for("refunds", "created", "refund"),
            IncomingWebhookEvent::EventNotSupported
        );
        assert_eq!(
            event_type_for("refunds", "paid", "refund"),
            IncomingWebhookEvent::RefundSuccess
        );
    }

View on GitHub (pinned to afd9284352)