Skip to content

Commit

Permalink
fix(protocol): Double timeout when email rule configured (#2934)
Browse files Browse the repository at this point in the history
This checks for a configured email rule while we are translating specified rules to protobuf. If we see an email rule, we double the specified timeout on a call to `Decide`.

Luckily, the call to `client.decide()` is where we specify `timeoutMs` for ConnectRPC, so this timeout adjustment is per-request instead of globally per SDK instance.

Closes #1697
  • Loading branch information
blaine-arcjet authored Jan 23, 2025
1 parent 68c7ea9 commit 23f9a9e
Showing 1 changed file with 17 additions and 2 deletions.
19 changes: 17 additions & 2 deletions protocol/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { DecideService } from "./proto/decide/v1alpha1/decide_connect.js";
import {
DecideRequest,
ReportRequest,
Rule,
} from "./proto/decide/v1alpha1/decide_pb.js";

// TODO: Dedupe with `errorMessage` in core
Expand Down Expand Up @@ -77,6 +78,16 @@ export function createClient(options: ClientOptions): Client {
): Promise<ArcjetDecision> {
const { log } = context;

let hasValidateEmail = false;
const protoRules: Rule[] = [];
for (const rule of rules) {
if (rule.type === "EMAIL") {
hasValidateEmail = true;
}

protoRules.push(ArcjetRuleToProtocol(rule));
}

// Build the request object from the Protobuf generated class.
const decideRequest = new DecideRequest({
sdkStack,
Expand All @@ -96,14 +107,16 @@ export function createClient(options: ClientOptions): Client {
extra: details.extra,
email: typeof details.email === "string" ? details.email : undefined,
},
rules: rules.map(ArcjetRuleToProtocol),
rules: protoRules,
});

log.debug("Decide request to %s", baseUrl);

const response = await client.decide(decideRequest, {
headers: { Authorization: `Bearer ${context.key}` },
timeoutMs: timeout,
// If an email rule is configured, we double the timeout.
// See https://github.com/arcjet/arcjet-js/issues/1697
timeoutMs: hasValidateEmail ? timeout * 2 : timeout,
});

const decision = ArcjetDecisionFromProtocol(response.decision);
Expand Down Expand Up @@ -163,6 +176,8 @@ export function createClient(options: ClientOptions): Client {
const reportPromise = client
.report(reportRequest, {
headers: { Authorization: `Bearer ${context.key}` },
// Rules don't execute during `Report` so we don't adjust the timeout
// if an email rule is configured.
timeoutMs: 2_000, // 2 seconds
})
.then((response) => {
Expand Down

0 comments on commit 23f9a9e

Please sign in to comment.