Truncate continued fractions Related: Cleaning up decimal numbers
Background
A continued fraction is a way to represent a real number as a sequence of integers in the following sense:
$$
x = a_0 + \cfrac{1}{a_1 + \cfrac{1}{a_2 + \cfrac{1}{\ddots + \cfrac{1}{a_n}}}} = [a_0; a_1,a_2,\cdots,a_n]
$$
Finite continued fractions represent rational numbers; infinite continued fractions represent irrational numbers. This challenge will focus on finite ones for the sake of simplicity.
Let's take \$\frac{277}{642}\$ as an example. It has the following continued fraction:
$$
\frac{277}{642} =
0 + \cfrac{1}{2 + \cfrac{1}{3 + \cfrac{1}{6 + \cfrac{1}{1 + \cfrac{1}{3 + \cfrac{1}{3}}}}}} =  [0;2, 3, 6, 1, 3, 3]
$$
If we truncate the continued fraction at various places, we get various approximations of the number \$\frac{277}{642}\$:
$$
\begin{array}{c|c|c|c}
 \style{font-family:inherit}{\text{Continued Fraction}} &amp; \style{font-family:inherit}{\text{Fraction}}
&amp; \style{font-family:inherit}{\text{Decimal}} &amp; \style{font-family:inherit}{\text{Relative error}}\\\hline
 [0] &amp; 0/1 &amp; 0.0\dots &amp; 1 \\\hline
 [0;2] &amp; 1/2 &amp; 0.50\dots &amp; 0.15 \\\hline
 [0;2,3] &amp; 3/7 &amp; 0.428\dots &amp; 0.0067 \\\hline
 [0;2,3,6] &amp; 19/44 &amp; 0.4318\dots &amp; 0.00082 \\\hline
 [0;2,3,6,1] &amp; 22/51 &amp; 0.43137\dots &amp; 0.00021 \\\hline
 [0;2,3,6,1,3] &amp; 85/197 &amp; 0.431472\dots &amp; 0.000018 \\\hline
 [0;2,3,6,1,3,3] &amp; 277/642 &amp; 0.4314641\dots &amp; 0
\end{array}
$$
These are called convergents of the given number. In fact, the convergents are the best approximations among all fractions with the same or lower denominator. This property was used in a proposed machine number system of rational numbers to find the approximation that fits in a machine word of certain number of bits.
(There are some subtle points around &quot;best approximation&quot;, but we will ignore it and just use the convergents. As a consequence, if your language/library has a &quot;best rational approximation&quot; built-in, it is unlikely to correctly solve the following task.)
Task
Given a rational number \$r\$ given as a finite continued fraction and a positive integer \$D\$, find the best approximation of \$r\$ among its convergents so that its denominator does not exceed \$D\$.
The continued fraction is guaranteed to be a finite sequence of integers, where the first number is non-negative, and the rest are strictly positive. You may output the result as a built-in rational number or two separate integers. The output fraction does not need to be reduced.
Standard code-golf rules apply. The shortest code in bytes wins.
Test cases
[0, 2, 3, 6, 1, 3, 3], 43 =&gt; 3/7
[0, 2, 3, 6, 1, 3, 3], 44 =&gt; 19/44
[5, 6, 7], 99 =&gt; 222/43
JavaScript (ES6),  72 68   67 bytes
Expects (max_denominator)(seq). Returns [numerator, denominator].

m=&gt;g=([v,...a],n=0,d=1,N=1,D=0)=&gt;(d+=D*v)&lt;=m?g(a,N,D,N*v+n,d):[N,D]

Try it online!
Commented
m =&gt;             // outer function taking m = maximum denominator
g = (            // inner recursive function taking:
  [v,            //   v = next term from the continued fraction
      ...a],     //   a[] = remaining terms
  n = 0,         //   n = previous numerator
  d = 1,         //   d = previous denominator
  N = 1,         //   N = current numerator
  D = 0          //   D = current denominator
) =&gt;             //
  (d += D * v)   // we compute the new denominator d = D * v + d
                 // this results in NaN if v is undefined,
                 // which forces the comparison to fail
  &lt;= m ?         // if it's less than or equal to m:
    g(           //   do a recursive call:
      a,         //     pass the remaining terms of the continued fraction
      N, D,      //     pass the current numerator and denominator
      N * v + n, //     pass the new numerator
      d          //     pass the new denominator
    )            //   end of recursive call
  :              // else:
    [N, D]       //   we're done: return [N, D]