Skip to content

Snippet

A callout with a timeout you chose

Named Credentials, an explicit timeout, and an error you can act on.

The default callout timeout is ten seconds, which is far too long to hold a user’s transaction and far too short for some batch endpoints. Set it deliberately either way.

public class BillingClient {
    private static final Integer TIMEOUT_MS = 8000;

    public class BillingException extends Exception {}

    public static InvoiceResponse fetch(String invoiceNumber) {
        HttpRequest req = new HttpRequest();
        // The credential name, not a URL and not a token. Nothing secret ever
        // appears in this class, which is what makes it safe to read in a PR.
        req.setEndpoint('callout:Billing_API/invoices/' + EncodingUtil.urlEncode(invoiceNumber, 'UTF-8'));
        req.setMethod('GET');
        req.setHeader('Accept', 'application/json');
        req.setTimeout(TIMEOUT_MS);

        HttpResponse res;
        try {
            res = new Http().send(req);
        } catch (System.CalloutException e) {
            // A timeout arrives here, not as a status code. Saying so in the
            // message saves the next person twenty minutes in the debug log.
            throw new BillingException('Billing API did not respond within ' +
                TIMEOUT_MS + 'ms: ' + e.getMessage(), e);
        }

        if (res.getStatusCode() == 404) return null;

        if (res.getStatusCode() >= 300) {
            throw new BillingException('Billing API returned ' + res.getStatusCode() +
                ': ' + res.getBody().abbreviate(500));
        }

        return (InvoiceResponse) JSON.deserialize(res.getBody(), InvoiceResponse.class);
    }

    public class InvoiceResponse {
        public String invoiceNumber;
        public Decimal amount;
        public String status;
    }
}

Three things worth copying: the URL-encoded path parameter, the separate catch for CalloutException so a timeout does not look like a bad response, and abbreviate(500) so a 5 MB HTML error page from a proxy does not blow the heap on its way into a log.

Keep reading

More snippets

All snippets
to move to open esc to close Full search