phacility/phabricator · error · Exception

Unsupported currency '%s'!

Error message

Unsupported currency '%s'!

What it means

PhortuneCurrency::newFromString parses amount strings like '19.99 USD'; the currency segment (explicit or defaulted) must be exactly USD - the only currency Phortune supports. Any other captured code ('5.00 EUR', '10 GBP') throws Exception "Unsupported currency '%s'!". Phortune is deliberately single-currency per install, so no exchange or multi-currency path exists.

Source

Thrown at src/applications/phortune/currency/PhortuneCurrency.php:55

    if (substr_count($value, '-') > 1) {
      self::throwFormatException($string);
    }

    if (substr_count($value, '$') > 1) {
      self::throwFormatException($string);
    }

    $value = str_replace('$', '', $value);
    $value = (float)$value;
    $value = (int)round(100 * $value);

    $currency = idx($matches, 2, $default);
    switch ($currency) {
      case 'USD':
        break;
      default:
        throw new Exception(pht("Unsupported currency '%s'!", $currency));
    }

    return self::newFromValueAndCurrency($value, $currency);
  }

  public static function newFromValueAndCurrency($value, $currency) {
    $obj = new PhortuneCurrency();

    $obj->value = $value;
    $obj->currency = $currency;

    return $obj;
  }

  public static function newFromList(array $list) {
    assert_instances_of($list, __CLASS__);

    if (!$list) {

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Use USD amounts: '19.99 USD' or a bare '19.99' (USD is the default)
  2. Convert foreign-currency prices to USD before feeding them into Phortune
  3. Do not extend the switch for other currencies unless you fully understand the single-currency assumption baked into Phortune

Example fix

// before
$price = PhortuneCurrency::newFromString('5.00 EUR');
// after
$price = PhortuneCurrency::newFromString('5.00 USD');
Defensive patterns

Strategy: validation

Validate before calling

// Normalize to USD before parsing
$value = strtoupper(trim($value));
if (preg_match('/(USD)$/', $value) !== 1) {
  $value = $value.' USD'; // or convert from the source currency first
}
$currency = PhortuneCurrency::newFromString($value);

Type guard

function isSupportedPhortuneCurrency($currency) {
  return is_string($currency) && strcasecmp($currency, 'USD') === 0;
}

Prevention

When it happens

Trigger: Passing '5.00 EUR', '10 GBP', or any non-USD code to PhortuneCurrency::newFromString; custom product code emitting localized currency strings; integrations formatting prices with the buyer's locale currency.

Common situations: Non-US developers testing with local currency strings; billing integrations reused from multi-currency systems; copy-pasted price strings including currency symbols or codes.

Related errors


AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21). Data as JSON: /api/errors/d291a1be0c30dfa5. Report an issue: GitHub.