# tree printing only changes deliberately

    Code
      print(trace, dir = dir)
    Output
          x
       1. \-rlang (local) i() at test-trace.R:25:3
       2.   \-rlang (local) j(i) at test-trace.R:18:8
       3.     \-rlang (local) k(i) at test-trace.R:19:22
       4.       \-rlang (local) l(i) at test-trace.R:22:5
    Code
      cat("\n")
    Output
      
    Code
      print(trace_slice(trace, 0L), dir = dir)
    Output
      x

# can print tree with collapsed branches

    Code
      # Full
      print(trace, simplify = "none", dir = dir, srcrefs = srcrefs)
    Output
           x
        1. \-rlang (local) f()
        2.   \-rlang (local) g() at test-trace.R:49:21
        3.     +-base::tryCatch(h(), foo = identity, bar = identity) at test-trace.R:50:21
        4.     | \-base (local) tryCatchList(expr, classes, parentenv, handlers)
        5.     |   +-base (local) tryCatchOne(...)
        6.     |   | \-base (local) doTryCatch(return(expr), name, parentenv, handler)
        7.     |   \-base (local) tryCatchList(expr, names[-nh], parentenv, handlers[-nh])
        8.     |     \-base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]])
        9.     |       \-base (local) doTryCatch(return(expr), name, parentenv, handler)
       10.     \-rlang (local) h()
       11.       +-base::tryCatch(i(), baz = identity) at test-trace.R:51:21
       12.       | \-base (local) tryCatchList(expr, classes, parentenv, handlers)
       13.       |   \-base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]])
       14.       |     \-base (local) doTryCatch(return(expr), name, parentenv, handler)
       15.       \-rlang (local) i()
       16.         +-base::tryCatch(trace_back(e, bottom = 0)) at test-trace.R:52:21
       17.         | \-base (local) tryCatchList(expr, classes, parentenv, handlers)
       18.         \-rlang::trace_back(e, bottom = 0)
    Code
      # Focused
      print_focused_trace(trace, dir = dir, srcrefs = srcrefs)
    Output
           x
        1. \-rlang (local) f()
        2.   \-rlang (local) g() at test-trace.R:49:21
        3.     +<<-base::tryCatch(h(), foo = identity, bar = identity) at test-trace.R:50:21>>
        4.     | <<\-base (local) tryCatchList(expr, classes, parentenv, handlers)>>
        5.     |   <<+-base (local) tryCatchOne(...)>>
        6.     |   <<| \-base (local) doTryCatch(return(expr), name, parentenv, handler)>>
        7.     |   <<\-base (local) tryCatchList(expr, names[-nh], parentenv, handlers[-nh])>>
        8.     |     <<\-base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]])>>
        9.     |       <<\-base (local) doTryCatch(return(expr), name, parentenv, handler)>>
       10.     \-rlang (local) h()
       11.       +<<-base::tryCatch(i(), baz = identity) at test-trace.R:51:21>>
       12.       | <<\-base (local) tryCatchList(expr, classes, parentenv, handlers)>>
       13.       |   <<\-base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]])>>
       14.       |     <<\-base (local) doTryCatch(return(expr), name, parentenv, handler)>>
       15.       \-rlang (local) i()
    Code
      # Branch
      print(trace, simplify = "branch", dir = dir, srcrefs = srcrefs)
    Output
        1. rlang (local) f()
        2. rlang (local) g()
             at test-trace.R:49:21
       10. rlang (local) h()
       15. rlang (local) i()

---

    Code
      # Full
      print(trace, simplify = "none", dir = dir, srcrefs = srcrefs)
    Output
           x
        1. \-rlang (local) f()
        2.   +-base::eval(quote(eval(quote(g())))) at test-trace.R:61:8
        3.   | \-base::eval(quote(eval(quote(g()))))
        4.   +-base::eval(quote(g()))
        5.   | \-base::eval(quote(g()))
        6.   \-rlang (local) g()
        7.     +-base::tryCatch(eval(quote(h())), foo = identity, bar = identity) at test-trace.R:62:8
        8.     | \-base (local) tryCatchList(expr, classes, parentenv, handlers)
        9.     |   +-base (local) tryCatchOne(...)
       10.     |   | \-base (local) doTryCatch(return(expr), name, parentenv, handler)
       11.     |   \-base (local) tryCatchList(expr, names[-nh], parentenv, handlers[-nh])
       12.     |     \-base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]])
       13.     |       \-base (local) doTryCatch(return(expr), name, parentenv, handler)
       14.     +-base::eval(quote(h()))
       15.     | \-base::eval(quote(h()))
       16.     \-rlang (local) h()
    Code
      # Focused
      print_focused_trace(trace, dir = dir, srcrefs = srcrefs)
    Output
           x
        1. \-rlang (local) f()
        2.   +<<-base::eval(quote(eval(quote(g())))) at test-trace.R:61:8>>
        3.   | <<\-base::eval(quote(eval(quote(g()))))>>
        4.   +<<-base::eval(quote(g()))>>
        5.   | <<\-base::eval(quote(g()))>>
        6.   \-rlang (local) g()
        7.     +<<-base::tryCatch(eval(quote(h())), foo = identity, bar = identity) at test-trace.R:62:8>>
        8.     | <<\-base (local) tryCatchList(expr, classes, parentenv, handlers)>>
        9.     |   <<+-base (local) tryCatchOne(...)>>
       10.     |   <<| \-base (local) doTryCatch(return(expr), name, parentenv, handler)>>
       11.     |   <<\-base (local) tryCatchList(expr, names[-nh], parentenv, handlers[-nh])>>
       12.     |     <<\-base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]])>>
       13.     |       <<\-base (local) doTryCatch(return(expr), name, parentenv, handler)>>
       14.     +<<-base::eval(quote(h()))>>
       15.     | <<\-base::eval(quote(h()))>>
       16.     \-rlang (local) h()
    Code
      # Branch
      print(trace, simplify = "branch", dir = dir, srcrefs = srcrefs)
    Output
        1. rlang (local) f()
        6. rlang (local) g()
       16. rlang (local) h()

# cli_branch() handles edge case

    Code
      cli_branch(tree[-1, ])
    Output
      [1] " 1. rlang (local) f()"

# collapsed formatting doesn't collapse single frame siblings

    Code
      print(trace, simplify = "none", drop = TRUE, srcrefs = FALSE)
    Output
          x
       1. \-rlang (local) f()
       2.   +-rlang::eval_bare(quote(g()))
       3.   \-rlang (local) g()
    Code
      print(trace, simplify = "none", drop = FALSE, srcrefs = FALSE)
    Output
          x
       1. \-rlang (local) f()
       2.   +-rlang::eval_bare(quote(g()))
       3.   \-rlang (local) g()

# recursive frames are rewired to the global env

    Code
      # Full
      print(trace, simplify = "none", dir = dir, srcrefs = srcrefs)
    Output
          x
       1. +-rlang::eval_tidy(quo(f()))
       2. \-rlang (local) f()
       3.   \-rlang (local) g()
    Code
      # Focused
      print_focused_trace(trace, dir = dir, srcrefs = srcrefs)
    Output
          x
       1. +-rlang::eval_tidy(quo(f()))
       2. \-rlang (local) f()
       3.   \-rlang (local) g()
    Code
      # Branch
      print(trace, simplify = "branch", dir = dir, srcrefs = srcrefs)
    Output
       1. rlang::eval_tidy(quo(f()))
       2. rlang (local) f()
       3. rlang (local) g()

# long backtrace branches are truncated

    Code
      cat("Full:\n")
    Output
      Full:
    Code
      print(trace, simplify = "branch", srcrefs = FALSE)
    Output
        1. rlang (local) f(10)
        2. rlang (local) f(n - 1)
        3. rlang (local) f(n - 1)
        4. rlang (local) f(n - 1)
        5. rlang (local) f(n - 1)
        6. rlang (local) f(n - 1)
        7. rlang (local) f(n - 1)
        8. rlang (local) f(n - 1)
        9. rlang (local) f(n - 1)
       10. rlang (local) f(n - 1)
       11. rlang (local) f(n - 1)
    Code
      cat("\n5 frames:\n")
    Output
      
      5 frames:
    Code
      print(trace, simplify = "branch", max_frames = 5, srcrefs = FALSE)
    Output
        1. rlang (local) f(10)
        2. rlang (local) f(n - 1)
        3. rlang (local) f(n - 1)
           ...
       10. rlang (local) f(n - 1)
       11. rlang (local) f(n - 1)
    Code
      cat("\n2 frames:\n")
    Output
      
      2 frames:
    Code
      print(trace, simplify = "branch", max_frames = 2, srcrefs = FALSE)
    Output
        1. rlang (local) f(10)
           ...
       11. rlang (local) f(n - 1)
    Code
      cat("\n1 frame:\n")
    Output
      
      1 frame:
    Code
      print(trace, simplify = "branch", max_frames = 1, srcrefs = FALSE)
    Output
        1. rlang (local) f(10)
           ...

# eval() frames are collapsed

    Code
      # Full
      print(trace, simplify = "none", dir = dir, srcrefs = srcrefs)
    Output
          x
       1. \-rlang (local) f()
       2.   +-base::eval(quote(g()))
       3.   | \-base::eval(quote(g()))
       4.   \-rlang (local) g()
       5.     +-base::eval(quote(trace_back(e, bottom = 0)))
       6.     | \-base::eval(quote(trace_back(e, bottom = 0)))
       7.     \-rlang::trace_back(e, bottom = 0)
    Code
      # Focused
      print_focused_trace(trace, dir = dir, srcrefs = srcrefs)
    Output
          x
       1. \-rlang (local) f()
       2.   +<<-base::eval(quote(g()))>>
       3.   | <<\-base::eval(quote(g()))>>
       4.   \-rlang (local) g()
    Code
      # Branch
      print(trace, simplify = "branch", dir = dir, srcrefs = srcrefs)
    Output
       1. rlang (local) f()
       4. rlang (local) g()

---

    Code
      # Full
      print(trace, simplify = "none", dir = dir, srcrefs = srcrefs)
    Output
          x
       1. \-rlang (local) f()
       2.   +-base::evalq(g())
       3.   | \-base::evalq(g())
       4.   \-rlang (local) g()
       5.     +-base::evalq(trace_back(e, bottom = 0))
       6.     | \-base::evalq(trace_back(e, bottom = 0))
       7.     \-rlang::trace_back(e, bottom = 0)
    Code
      # Focused
      print_focused_trace(trace, dir = dir, srcrefs = srcrefs)
    Output
          x
       1. \-rlang (local) f()
       2.   +<<-base::evalq(g())>>
       3.   | <<\-base::evalq(g())>>
       4.   \-rlang (local) g()
    Code
      # Branch
      print(trace, simplify = "branch", dir = dir, srcrefs = srcrefs)
    Output
       1. rlang (local) f()
       4. rlang (local) g()

# children of collapsed frames are rechained to correct parent

    Code
      cat("Full + drop:\n")
    Output
      Full + drop:
    Code
      print(trace, simplify = "none", drop = TRUE, srcrefs = FALSE)
    Output
          x
       1. \-rlang (local) f()
       2.   \-base::eval(quote(g()), env())
       3.     \-base::eval(quote(g()), env())
       4.       \-rlang (local) g()
    Code
      cat("Full - drop:\n")
    Output
      Full - drop:
    Code
      print(trace, simplify = "none", drop = FALSE, srcrefs = FALSE)
    Output
          x
       1. \-rlang (local) f()
       2.   \-base::eval(quote(g()), env())
       3.     \-base::eval(quote(g()), env())
       4.       \-rlang (local) g()
    Code
      cat("\nBranch:\n")
    Output
      
      Branch:
    Code
      print(trace, simplify = "branch", srcrefs = FALSE)
    Output
       1. rlang (local) f()
       2. base::eval(quote(g()), env())
       3. base::eval(quote(g()), env())
       4. rlang (local) g()

# combinations of incomplete and leading pipes collapse properly

    Code
      # Full
      print(trace, simplify = "none", dir = dir, srcrefs = srcrefs)
    Output
          x
       1. +-NA %>% F() %>% T() %>% F() %>% F()
       2. +-rlang (local) F(.)
       3. +-rlang (local) F(.)
       4. \-rlang (local) T(.)
    Code
      # Focused
      print_focused_trace(trace, dir = dir, srcrefs = srcrefs)
    Output
          x
       1. +-NA %>% F() %>% T() %>% F() %>% F()
       2. +-rlang (local) F(.)
       3. +-rlang (local) F(.)
       4. \-rlang (local) T(.)
    Code
      # Branch
      print(trace, simplify = "branch", dir = dir, srcrefs = srcrefs)
    Output
       1. NA %>% F() %>% T() %>% F() %>% F()
       4. rlang (local) T(.)

---

    Code
      # Full
      print(trace, simplify = "none", dir = dir, srcrefs = srcrefs)
    Output
          x
       1. +-T(NA) %>% F()
       2. +-rlang (local) F(.)
       3. \-rlang (local) T(NA)
    Code
      # Focused
      print_focused_trace(trace, dir = dir, srcrefs = srcrefs)
    Output
          x
       1. +-T(NA) %>% F()
       2. +-rlang (local) F(.)
       3. \-rlang (local) T(NA)
    Code
      # Branch
      print(trace, simplify = "branch", dir = dir, srcrefs = srcrefs)
    Output
       1. T(NA) %>% F()
       3. rlang (local) T(NA)

---

    Code
      # Full
      print(trace, simplify = "none", dir = dir, srcrefs = srcrefs)
    Output
          x
       1. +-F(NA) %>% F() %>% T() %>% F() %>% F()
       2. +-rlang (local) F(.)
       3. +-rlang (local) F(.)
       4. \-rlang (local) T(.)
    Code
      # Focused
      print_focused_trace(trace, dir = dir, srcrefs = srcrefs)
    Output
          x
       1. +-F(NA) %>% F() %>% T() %>% F() %>% F()
       2. +-rlang (local) F(.)
       3. +-rlang (local) F(.)
       4. \-rlang (local) T(.)
    Code
      # Branch
      print(trace, simplify = "branch", dir = dir, srcrefs = srcrefs)
    Output
       1. F(NA) %>% F() %>% T() %>% F() %>% F()
       4. rlang (local) T(.)

---

    Code
      # Full
      print(trace, simplify = "none", dir = dir, srcrefs = srcrefs)
    Output
          x
       1. +-NA %>% T()
       2. \-rlang (local) T(.)
    Code
      # Focused
      print_focused_trace(trace, dir = dir, srcrefs = srcrefs)
    Output
          x
       1. +-NA %>% T()
       2. \-rlang (local) T(.)
    Code
      # Branch
      print(trace, simplify = "branch", dir = dir, srcrefs = srcrefs)
    Output
       1. NA %>% T()
       2. rlang (local) T(.)

---

    Code
      # Full
      print(trace, simplify = "none", dir = dir, srcrefs = srcrefs)
    Output
          x
       1. +-NA %>% F() %>% T()
       2. \-rlang (local) T(.)
    Code
      # Focused
      print_focused_trace(trace, dir = dir, srcrefs = srcrefs)
    Output
          x
       1. +-NA %>% F() %>% T()
       2. \-rlang (local) T(.)
    Code
      # Branch
      print(trace, simplify = "branch", dir = dir, srcrefs = srcrefs)
    Output
       1. NA %>% F() %>% T()
       2. rlang (local) T(.)

---

    Code
      # Full
      print(trace, simplify = "none", dir = dir, srcrefs = srcrefs)
    Output
          x
       1. +-F(NA) %>% T()
       2. \-rlang (local) T(.)
    Code
      # Focused
      print_focused_trace(trace, dir = dir, srcrefs = srcrefs)
    Output
          x
       1. +-F(NA) %>% T()
       2. \-rlang (local) T(.)
    Code
      # Branch
      print(trace, simplify = "branch", dir = dir, srcrefs = srcrefs)
    Output
       1. F(NA) %>% T()
       2. rlang (local) T(.)

---

    Code
      # Full
      print(trace, simplify = "none", dir = dir, srcrefs = srcrefs)
    Output
          x
       1. +-F(NA) %>% F() %>% T()
       2. \-rlang (local) T(.)
    Code
      # Focused
      print_focused_trace(trace, dir = dir, srcrefs = srcrefs)
    Output
          x
       1. +-F(NA) %>% F() %>% T()
       2. \-rlang (local) T(.)
    Code
      # Branch
      print(trace, simplify = "branch", dir = dir, srcrefs = srcrefs)
    Output
       1. F(NA) %>% F() %>% T()
       2. rlang (local) T(.)

# calls before and after pipe are preserved

    Code
      # Full
      print(trace, simplify = "none", dir = dir, srcrefs = srcrefs)
    Output
          x
       1. +-rlang (local) F(NA %>% T())
       2. +-NA %>% T()
       3. \-rlang (local) T(.)
    Code
      # Focused
      print_focused_trace(trace, dir = dir, srcrefs = srcrefs)
    Output
          x
       1. +-rlang (local) F(NA %>% T())
       2. +-NA %>% T()
       3. \-rlang (local) T(.)
    Code
      # Branch
      print(trace, simplify = "branch", dir = dir, srcrefs = srcrefs)
    Output
       1. rlang (local) F(NA %>% T())
       3. rlang (local) T(.)

---

    Code
      # Full
      print(trace, simplify = "none", dir = dir, srcrefs = srcrefs)
    Output
          x
       1. +-NA %>% C()
       2. \-rlang (local) C(.)
       3.   \-rlang (local) f()
    Code
      # Focused
      print_focused_trace(trace, dir = dir, srcrefs = srcrefs)
    Output
          x
       1. +-NA %>% C()
       2. \-rlang (local) C(.)
       3.   \-rlang (local) f()
    Code
      # Branch
      print(trace, simplify = "branch", dir = dir, srcrefs = srcrefs)
    Output
       1. NA %>% C()
       2. rlang (local) C(.)
       3. rlang (local) f()

---

    Code
      # Full
      print(trace, simplify = "none", dir = dir, srcrefs = srcrefs)
    Output
          x
       1. +-rlang (local) F(NA %>% C())
       2. +-NA %>% C()
       3. \-rlang (local) C(.)
       4.   \-rlang (local) f()
    Code
      # Focused
      print_focused_trace(trace, dir = dir, srcrefs = srcrefs)
    Output
          x
       1. +-rlang (local) F(NA %>% C())
       2. +-NA %>% C()
       3. \-rlang (local) C(.)
       4.   \-rlang (local) f()
    Code
      # Branch
      print(trace, simplify = "branch", dir = dir, srcrefs = srcrefs)
    Output
       1. rlang (local) F(NA %>% C())
       3. rlang (local) C(.)
       4. rlang (local) f()

# always keep very first frame as part of backtrace branch

    Code
      # Full
      print(trace, simplify = "none", dir = dir, srcrefs = srcrefs)
    Output
          x
       1. +-rlang (local) gen()
       2. \-rlang (local) gen.default()
    Code
      # Focused
      print_focused_trace(trace, dir = dir, srcrefs = srcrefs)
    Output
          x
       1. +-rlang (local) gen()
       2. \-rlang (local) gen.default()
    Code
      # Branch
      print(trace, simplify = "branch", dir = dir, srcrefs = srcrefs)
    Output
       1. rlang (local) gen()
       2. rlang (local) gen.default()

# anonymous calls are stripped from backtraces

    Code
      # Full
      print(trace, simplify = "none", dir = dir, srcrefs = srcrefs)
    Output
          x
       1. \-(function() {...
    Code
      # Focused
      print_focused_trace(trace, dir = dir, srcrefs = srcrefs)
    Output
          x
       1. \-(function() {...
    Code
      # Branch
      print(trace, simplify = "branch", dir = dir, srcrefs = srcrefs)
    Output
      

# collapsing of eval() frames detects when error occurs within eval()

    Code
      # Full
      print(trace, simplify = "none", dir = dir, srcrefs = srcrefs)
    Output
          x
       1. +-base::eval()
       2. \-base::.handleSimpleError(...)
       3.   \-rlang (local) h(simpleError(msg, call))
    Code
      # Focused
      print_focused_trace(trace, dir = dir, srcrefs = srcrefs)
    Output
          x
       1. +-base::eval()
       2. \-base::.handleSimpleError(...)
       3.   \-rlang (local) h(simpleError(msg, call))
    Code
      # Branch
      print(trace, simplify = "branch", dir = dir, srcrefs = srcrefs)
    Output
       1. base::eval()
       2. base::.handleSimpleError(...)
       3. rlang (local) h(simpleError(msg, call))

# can print degenerate backtraces

    Code
      # Full
      print(trace, simplify = "none", dir = dir, srcrefs = srcrefs)
    Output
          x
       1. \-foo
    Code
      # Focused
      print_focused_trace(trace, dir = dir, srcrefs = srcrefs)
    Output
          x
       1. \-foo
    Code
      # Branch
      print(trace, simplify = "branch", dir = dir, srcrefs = srcrefs)
    Output
       1. foo

---

    Code
      # Full
      print(trace, simplify = "none", dir = dir, srcrefs = srcrefs)
    Output
          x
       1. \-NULL
    Code
      # Focused
      print_focused_trace(trace, dir = dir, srcrefs = srcrefs)
    Output
          x
       1. \-NULL
    Code
      # Branch
      print(trace, simplify = "branch", dir = dir, srcrefs = srcrefs)
    Output
       1. NULL

---

    Code
      # Full
      print(trace, simplify = "none", dir = dir, srcrefs = srcrefs)
    Output
          x
       1. \-1L
    Code
      # Focused
      print_focused_trace(trace, dir = dir, srcrefs = srcrefs)
    Output
          x
       1. \-1L
    Code
      # Branch
      print(trace, simplify = "branch", dir = dir, srcrefs = srcrefs)
    Output
       1. 1L

# check for dangling promise in call CAR (#492)

    Code
      # Full
      print(trace, simplify = "none", dir = dir, srcrefs = srcrefs)
    Output
          x
       1. +-base::print(foo)
       2. \-rlang (local) print.foo(foo)
    Code
      # Focused
      print_focused_trace(trace, dir = dir, srcrefs = srcrefs)
    Output
          x
       1. +-base::print(foo)
       2. \-rlang (local) print.foo(foo)
    Code
      # Branch
      print(trace, simplify = "branch", dir = dir, srcrefs = srcrefs)
    Output
       1. base::print(foo)
       2. rlang (local) print.foo(foo)

# dangling srcrefs are not printed

    Code
      # Full
      print(trace, simplify = "none", dir = dir, srcrefs = srcrefs)
    Output
          x
       1. \-rlang (local) f(current_env())
       2.   \-rlang (local) g(e) at fixtures/trace-srcref2.R:2:3
    Code
      # Focused
      print_focused_trace(trace, dir = dir, srcrefs = srcrefs)
    Output
          x
       1. \-rlang (local) f(current_env())
       2.   \-rlang (local) g(e) at fixtures/trace-srcref2.R:2:3
    Code
      # Branch
      print(trace, simplify = "branch", dir = dir, srcrefs = srcrefs)
    Output
       1. rlang (local) f(current_env())
       2. rlang (local) g(e)
            at fixtures/trace-srcref2.R:2:3

# summary.rlang_trace() prints the full tree

    Code
      summary(trace, srcrefs = FALSE)
    Output
          x
       1. \-rlang (local) f()
       2.   \-rlang (local) g()
       3.     \-rlang (local) h()

# global functions have `global::` prefix

    Code
      # Full
      print(trace, simplify = "none", dir = dir, srcrefs = srcrefs)
    Output
          x
       1. \-rlang (local) g(current_env())
       2.   \-global f(e)
    Code
      # Focused
      print_focused_trace(trace, dir = dir, srcrefs = srcrefs)
    Output
          x
       1. \-rlang (local) g(current_env())
       2.   \-global f(e)
    Code
      # Branch
      print(trace, simplify = "branch", dir = dir, srcrefs = srcrefs)
    Output
       1. rlang (local) g(current_env())
       2. global f(e)

# local functions inheriting from global do not have `global::` prefix

    Code
      # Full
      print(trace, simplify = "none", dir = dir, srcrefs = srcrefs)
    Output
          x
       1. \-rlang (local) g(current_env())
       2.   \-f(e)
    Code
      # Focused
      print_focused_trace(trace, dir = dir, srcrefs = srcrefs)
    Output
          x
       1. \-rlang (local) g(current_env())
       2.   \-f(e)
    Code
      # Branch
      print(trace, simplify = "branch", dir = dir, srcrefs = srcrefs)
    Output
       1. rlang (local) g(current_env())
       2. f(e)

# can trim layers of backtraces

    Code
      local_options(rlang_trace_format_srcrefs = FALSE)
      cat_line("No trimming:")
    Output
      No trimming:
    Code
      summary(trace0)
    Output
           x
        1. \-rlang (local) f(0) at test-trace.R:412:3
        2.   +-base::identity(identity(g(n))) at test-trace.R:408:8
        3.   +-base::identity(g(n))
        4.   \-rlang (local) g(n)
        5.     +-base::identity(identity(h(n))) at test-trace.R:409:8
        6.     +-base::identity(h(n))
        7.     \-rlang (local) h(n)
        8.       +-base::identity(identity(trace_back(e, bottom = n))) at test-trace.R:410:8
        9.       +-base::identity(trace_back(e, bottom = n))
       10.       \-rlang::trace_back(e, bottom = n)
    Code
      cat_line("", "", "One layer (the default):")
    Output
      
      
      One layer (the default):
    Code
      summary(trace1)
    Output
          x
       1. \-rlang (local) f(1) at test-trace.R:413:3
       2.   +-base::identity(identity(g(n))) at test-trace.R:408:8
       3.   +-base::identity(g(n))
       4.   \-rlang (local) g(n)
       5.     +-base::identity(identity(h(n))) at test-trace.R:409:8
       6.     +-base::identity(h(n))
       7.     \-rlang (local) h(n)
    Code
      cat_line("", "", "Two layers:")
    Output
      
      
      Two layers:
    Code
      summary(trace2)
    Output
          x
       1. \-rlang (local) f(2) at test-trace.R:414:3
       2.   +-base::identity(identity(g(n))) at test-trace.R:408:8
       3.   +-base::identity(g(n))
       4.   \-rlang (local) g(n)
    Code
      cat_line("", "", "Three layers:")
    Output
      
      
      Three layers:
    Code
      summary(trace3)
    Output
          x
       1. \-rlang (local) f(3) at test-trace.R:415:3

# caught error does not display backtrace in knitted files

    Code
      cat_line(render_md("test-trace-full.Rmd"))
    Output
          library(rlang)
      
          f <- function() g()
          g <- function() h()
          h <- function() rlang::abort("foo")
      
          f()
      
          ## Error in `h()`:
          ## ! foo
      
      Currently needs to be in a different chunk:
      
          last_error()
      
          ## <error/rlang_error>
          ## Error in `h()`:
          ## ! foo
          ## ---
          ## Backtrace:
          ##     x
          ##  1. \-global f()
          ##  2.   \-global g()
          ##  3.     \-global h()
          ## Run rlang::last_trace(drop = FALSE) to see 1 hidden frame.
      
          last_trace()
      
          ## <error/rlang_error>
          ## Error in `h()`:
          ## ! foo
          ## ---
          ## Backtrace:
          ##     x
          ##  1. \-global f()
          ##  2.   \-global g()
          ##  3.     \-global h()
          ## Run rlang::last_trace(drop = FALSE) to see 1 hidden frame.
      
          options(rlang_backtrace_on_error_report = "reminder")
          f()
      
          ## Error in `h()`:
          ## ! foo
          ## Run `rlang::last_trace()` to see where the error occurred.
      
          options(rlang_backtrace_on_error_report = "full")
          f()
      
          ## Error in `h()`:
          ## ! foo
          ## Backtrace:
          ##     x
          ##  1. \-global f()
          ##  2.   \-global g()
          ##  3.     \-global h()
          ##  4.       \-rlang::abort("foo")

# backtraces don't contain inlined objects (#1069, r-lib/testthat#1223)

    Code
      summary(trace)
    Output
          x
       1. +-rlang::inject(f(!!list()))
       2. \-rlang (local) f(`<list>`)
       3.   +-base::do.call("g", list(runif(1e+06) + 0))
       4.   \-rlang (local) g(`<dbl>`)
       5.     \-rlang (local) h()

# runs of namespaces are embolden (#946)

    Code
      print(err)
    Output
      [1m[34m<error/rlang_error>[39m[22m
      [1m[33mError[39m in [1m[94m`1 + ""`[39m[1m:[22m
      [33m![39m non-numeric argument to binary operator
      ---
      [1mBacktrace:[22m
      [90m     [39mx
      [90m  1. [39m+-[1mrlang[22m::catch_cnd(withCallingHandlers(f(), error = entrace), "error")
      [90m  2. [39m| [90m+-rlang::eval_bare(...)[39m
      [90m  3. [39m| [90m+-[1mbase[22m::tryCatch(...)[39m
      [90m  4. [39m| [90m| \-base (local) tryCatchList(expr, classes, parentenv, handlers)[39m
      [90m  5. [39m| [90m|   \-base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]])[39m
      [90m  6. [39m| [90m|     \-base (local) doTryCatch(return(expr), name, parentenv, handler)[39m
      [90m  7. [39m| [90m\-base::force(expr)[39m
      [90m  8. [39m+-base::withCallingHandlers(f(), error = entrace)
      [90m  9. [39m\-[1mrlang[22m (local) f()
      [90m 10. [39m  \-rlang (local) g()
      [90m 11. [39m    \-rlang (local) h()
      [90m 12. [39m      \-[1mbase[22m::identity(1 + "")
    Code
      summary(err)
    Output
      [1m[34m<error/rlang_error>[39m[22m
      [1m[33mError[39m in [1m[94m`1 + ""`[39m[1m:[22m
      [33m![39m non-numeric argument to binary operator
      ---
      [1mBacktrace:[22m
      [90m     [39mx
      [90m  1. [39m+-[1mrlang[22m::catch_cnd(withCallingHandlers(f(), error = entrace), "error")
      [90m  2. [39m| [90m+-rlang::eval_bare(...)[39m
      [90m  3. [39m| [90m+-[1mbase[22m::tryCatch(...)[39m
      [90m  4. [39m| [90m| \-base (local) tryCatchList(expr, classes, parentenv, handlers)[39m
      [90m  5. [39m| [90m|   \-base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]])[39m
      [90m  6. [39m| [90m|     \-base (local) doTryCatch(return(expr), name, parentenv, handler)[39m
      [90m  7. [39m| [90m\-base::force(expr)[39m
      [90m  8. [39m+-base::withCallingHandlers(f(), error = entrace)
      [90m  9. [39m\-[1mrlang[22m (local) f()
      [90m 10. [39m  \-rlang (local) g()
      [90m 11. [39m    \-rlang (local) h()
      [90m 12. [39m      \-[1mbase[22m::identity(1 + "")

# `bottom` must be a positive integer

    Code
      (expect_error(trace_back(bottom = -1)))
    Output
      <error/rlang_error>
      Error in `trace_back()`:
      ! `bottom` must be a positive integer.

# collapsed case in branch formatting

     1. f()
     2. g()
     3. h()
     4. evalq()
     5. evalq()

# trailing `FALSE` visibility is handled

    Code
      # Full
      print(trace, simplify = "none", dir = dir, srcrefs = srcrefs)
    Output
          x
       1. \-f()
       2.   \-g()
       3.     \-h()
       4.       \-foo()
       5.         \-bar()
    Code
      # Focused
      print_focused_trace(trace, dir = dir, srcrefs = srcrefs)
    Output
          x
       1. \-f()
       2.   \-g()
       3.     \-h()
    Code
      # Branch
      print(trace, simplify = "branch", dir = dir, srcrefs = srcrefs)
    Output
       1. f()
       2. g()
       3. h()

# can format empty traces

    Code
      # Full
      print(trace, simplify = "none", dir = dir, srcrefs = srcrefs)
    Output
      x
    Code
      # Focused
      print_focused_trace(trace, dir = dir, srcrefs = srcrefs)
    Output
      x
    Code
      # Branch
      print(trace, simplify = "branch", dir = dir, srcrefs = srcrefs)
    Output
      

# sibling streaks in tree backtraces

    Code
      # Full
      print(trace, simplify = "none", dir = dir, srcrefs = srcrefs)
    Output
      <error/rlang_error>
      Error in `h()`:
      ! foo
      ---
      Backtrace:
           x
        1. +-rlang::catch_cnd(f(g()), "error")
        2. | +-rlang::eval_bare(...)
        3. | +-base::tryCatch(...)
        4. | | \-base (local) tryCatchList(expr, classes, parentenv, handlers)
        5. | |   \-base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]])
        6. | |     \-base (local) doTryCatch(return(expr), name, parentenv, handler)
        7. | \-base::force(expr)
        8. +-rlang (local) f(g())
        9. | +-base::identity(identity(x))
       10. | \-base::identity(x)
       11. \-rlang (local) g()
       12.   +-rlang (local) f(f(h()))
       13.   | +-base::identity(identity(x))
       14.   | \-base::identity(x)
       15.   +-rlang (local) f(h())
       16.   | +-base::identity(identity(x))
       17.   | \-base::identity(x)
       18.   \-rlang (local) h()
    Code
      # Focused
      print_focused_trace(trace, dir = dir, srcrefs = srcrefs)
    Output
      <error/rlang_error>
      Error in `h()`:
      ! foo
      ---
      Backtrace:
           x
        1. +-rlang::catch_cnd(f(g()), "error")
        2. | <<+-rlang::eval_bare(...)>>
        3. | <<+-base::tryCatch(...)>>
        4. | <<| \-base (local) tryCatchList(expr, classes, parentenv, handlers)>>
        5. | <<|   \-base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]])>>
        6. | <<|     \-base (local) doTryCatch(return(expr), name, parentenv, handler)>>
        7. | <<\-base::force(expr)>>
        8. +-rlang (local) f(g())
        9. | <<+-base::identity(identity(x))>>
       10. | <<\-base::identity(x)>>
       11. \-rlang (local) g()
       12.   +<<-rlang (local) f(f(h()))>>
       13.   | <<+-base::identity(identity(x))>>
       14.   | <<\-base::identity(x)>>
       15.   +<<-rlang (local) f(h())>>
       16.   | <<+-base::identity(identity(x))>>
       17.   | <<\-base::identity(x)>>
       18.   \-rlang (local) h()
    Code
      # Branch
      print(trace, simplify = "branch", dir = dir, srcrefs = srcrefs)
    Output
      <error/rlang_error>
      Error in `h()`:
      ! foo
      ---
      Backtrace:
        1. rlang::catch_cnd(f(g()), "error")
       11. rlang (local) g()
       18. rlang (local) h()

# parallel '|' branches are correctly emphasised

    Code
      # Full
      print(trace, simplify = "none", dir = dir, srcrefs = srcrefs)
    Output
      <error/rlang_error>
      Error in `h()`:
      ! foo
      ---
      Backtrace:
           x
        1. +-testthat::expect_error(parallel(f(0)))
        2. | \-testthat:::expect_condition_matching(...)
        3. |   \-testthat:::quasi_capture(...)
        4. |     +-testthat (local) .capture(...)
        5. |     | \-base::withCallingHandlers(...)
        6. |     \-rlang::eval_bare(quo_get_expr(.quo), quo_get_env(.quo))
        7. +-rlang (local) parallel(f(0))
        8. | +-rlang (local) p1(identity(x))
        9. | | \-rlang (local) p2(x)
       10. | |   \-rlang (local) p3(x)
       11. | \-base::identity(x)
       12. \-rlang (local) f(0)
       13.   \-rlang (local) g(n)
       14.     \-rlang (local) h(n)
    Code
      # Focused
      print_focused_trace(trace, dir = dir, srcrefs = srcrefs)
    Output
      <error/rlang_error>
      Error in `h()`:
      ! foo
      ---
      Backtrace:
           x
        1. +-testthat::expect_error(parallel(f(0)))
        2. | <<\-testthat:::expect_condition_matching(...)>>
        3. |   <<\-testthat:::quasi_capture(...)>>
        4. |     <<+-testthat (local) .capture(...)>>
        5. |     <<| \-base::withCallingHandlers(...)>>
        6. |     <<\-rlang::eval_bare(quo_get_expr(.quo), quo_get_env(.quo))>>
        7. +-rlang (local) parallel(f(0))
        8. | <<+-rlang (local) p1(identity(x))>>
        9. | <<| \-rlang (local) p2(x)>>
       10. | <<|   \-rlang (local) p3(x)>>
       11. | <<\-base::identity(x)>>
       12. \-rlang (local) f(0)
       13.   \-rlang (local) g(n)
       14.     \-rlang (local) h(n)
    Code
      # Branch
      print(trace, simplify = "branch", dir = dir, srcrefs = srcrefs)
    Output
      <error/rlang_error>
      Error in `h()`:
      ! foo
      ---
      Backtrace:
        1. testthat::expect_error(parallel(f(0)))
       12. rlang (local) f(0)
       13. rlang (local) g(n)
       14. rlang (local) h(n)

---

    Code
      # Full
      print(trace, simplify = "none", dir = dir, srcrefs = srcrefs)
    Output
      <error/rlang_error>
      Error in `h()`:
      ! foo
      ---
      Backtrace:
           x
        1. +-testthat::expect_error(deep(1))
        2. | \-testthat:::expect_condition_matching(...)
        3. |   \-testthat:::quasi_capture(...)
        4. |     +-testthat (local) .capture(...)
        5. |     | \-base::withCallingHandlers(...)
        6. |     \-rlang::eval_bare(quo_get_expr(.quo), quo_get_env(.quo))
        7. \-rlang (local) deep(1)
        8.   +-rlang (local) parallel(f(n))
        9.   | +-rlang (local) p1(identity(x))
       10.   | | \-rlang (local) p2(x)
       11.   | |   \-rlang (local) p3(x)
       12.   | \-base::identity(x)
       13.   \-rlang (local) f(n)
       14.     \-rlang (local) g(n)
       15.       \-rlang (local) h(n)
       16.         +-rlang (local) parallel(f(n - 1))
       17.         | +-rlang (local) p1(identity(x))
       18.         | | \-rlang (local) p2(x)
       19.         | |   \-rlang (local) p3(x)
       20.         | \-base::identity(x)
       21.         \-rlang (local) f(n - 1)
       22.           \-rlang (local) g(n)
       23.             \-rlang (local) h(n)
    Code
      # Focused
      print_focused_trace(trace, dir = dir, srcrefs = srcrefs)
    Output
      <error/rlang_error>
      Error in `h()`:
      ! foo
      ---
      Backtrace:
           x
        1. +-testthat::expect_error(deep(1))
        2. | <<\-testthat:::expect_condition_matching(...)>>
        3. |   <<\-testthat:::quasi_capture(...)>>
        4. |     <<+-testthat (local) .capture(...)>>
        5. |     <<| \-base::withCallingHandlers(...)>>
        6. |     <<\-rlang::eval_bare(quo_get_expr(.quo), quo_get_env(.quo))>>
        7. \-rlang (local) deep(1)
        8.   +<<-rlang (local) parallel(f(n))>>
        9.   | <<+-rlang (local) p1(identity(x))>>
       10.   | <<| \-rlang (local) p2(x)>>
       11.   | <<|   \-rlang (local) p3(x)>>
       12.   | <<\-base::identity(x)>>
       13.   \-rlang (local) f(n)
       14.     \-rlang (local) g(n)
       15.       \-rlang (local) h(n)
       16.         +<<-rlang (local) parallel(f(n - 1))>>
       17.         | <<+-rlang (local) p1(identity(x))>>
       18.         | <<| \-rlang (local) p2(x)>>
       19.         | <<|   \-rlang (local) p3(x)>>
       20.         | <<\-base::identity(x)>>
       21.         \-rlang (local) f(n - 1)
       22.           \-rlang (local) g(n)
       23.             \-rlang (local) h(n)
    Code
      # Branch
      print(trace, simplify = "branch", dir = dir, srcrefs = srcrefs)
    Output
      <error/rlang_error>
      Error in `h()`:
      ! foo
      ---
      Backtrace:
        1. testthat::expect_error(deep(1))
        7. rlang (local) deep(1)
       13. rlang (local) f(n)
       14. rlang (local) g(n)
       15. rlang (local) h(n)
       21. rlang (local) f(n - 1)
       22. rlang (local) g(n)
       23. rlang (local) h(n)

# error calls and args are highlighted

    Code
      print_highlighted_trace(parent)
    Output
      <error/rlang_error>
      Error in <<CALL `h()`>>:
      ! `x` must be a single string, not the number 1.
      ---
      Backtrace:
           x
        1. +-rlang:::catch_error(f(1))
        2. | \-rlang::catch_cnd(expr, "error")
        3. |   +-rlang::eval_bare(...)
        4. |   +-base::tryCatch(...)
        5. |   | \-base (local) tryCatchList(expr, classes, parentenv, handlers)
        6. |   |   \-base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]])
        7. |   |     \-base (local) doTryCatch(return(expr), name, parentenv, handler)
        8. |   \-base::force(expr)
        9. \-rlang (local) f(1)
       10.   \-rlang (local) g(x)
       11.     \-rlang (local) <<CALL h(>><<ARG x = x>><<CALL )>>
    Code
      print_highlighted_trace(child)
    Output
      <error/rlang_error>
      Error in <<CALL `wrapper()`>>:
      ! Tilt.
      Caused by error in <<CALL `h()`>>:
      ! `x` must be a single string, not the number 1.
      ---
      Backtrace:
           x
        1. +-rlang:::catch_error(wrapper())
        2. | \-rlang::catch_cnd(expr, "error")
        3. |   +-rlang::eval_bare(...)
        4. |   +-base::tryCatch(...)
        5. |   | \-base (local) tryCatchList(expr, classes, parentenv, handlers)
        6. |   |   \-base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]])
        7. |   |     \-base (local) doTryCatch(return(expr), name, parentenv, handler)
        8. |   \-base::force(expr)
        9. \-rlang (local) wrapper()
       10.   +-rlang::try_fetch(f(1), error = function(cnd) abort("Tilt.", parent = cnd))
       11.   | +-base::tryCatch(...)
       12.   | | \-base (local) tryCatchList(expr, classes, parentenv, handlers)
       13.   | |   \-base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]])
       14.   | |     \-base (local) doTryCatch(return(expr), name, parentenv, handler)
       15.   | \-base::withCallingHandlers(...)
       16.   \-rlang (local) f(1)
       17.     \-rlang (local) g(x)
       18.       \-rlang (local) <<CALL h(>><<ARG x = x>><<CALL )>>

# error calls and args are highlighted (no highlighted arg)

    Code
      print_highlighted_trace(argless)
    Output
      <error/rlang_error>
      Error in <<CALL `h()`>>:
      ! foo
      ---
      Backtrace:
           x
        1. +-rlang:::catch_error(f())
        2. | \-rlang::catch_cnd(expr, "error")
        3. |   +-rlang::eval_bare(...)
        4. |   +-base::tryCatch(...)
        5. |   | \-base (local) tryCatchList(expr, classes, parentenv, handlers)
        6. |   |   \-base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]])
        7. |   |     \-base (local) doTryCatch(return(expr), name, parentenv, handler)
        8. |   \-base::force(expr)
        9. \-rlang (local) f()
       10.   \-rlang (local) g()
       11.     \-rlang (local) <<CALL h(>><<CALL )>>

# frame is detected from the left

    Code
      # If detected from the right, `evalq()`is highlighted instead of `h()`
      print_highlighted_trace(err)
    Output
      <error/rlang_error>
      Error in <<CALL `h()`>>:
      ! foo
      ---
      Backtrace:
           x
        1. +-rlang:::catch_error(f())
        2. | \-rlang::catch_cnd(expr, "error")
        3. |   +-rlang::eval_bare(...)
        4. |   +-base::tryCatch(...)
        5. |   | \-base (local) tryCatchList(expr, classes, parentenv, handlers)
        6. |   |   \-base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]])
        7. |   |     \-base (local) doTryCatch(return(expr), name, parentenv, handler)
        8. |   \-base::force(expr)
        9. \-rlang (local) f()
       10.   \-rlang (local) g()
       11.     \-rlang (local) <<CALL h(>><<CALL )>>

# arg is defensively checked

    Code
      print_highlighted_trace(err)
    Output
      <error/rlang_error>
      Error in <<CALL `h()`>>:
      ! foo
      ---
      Backtrace:
           x
        1. +-rlang:::catch_error(f())
        2. | \-rlang::catch_cnd(expr, "error")
        3. |   +-rlang::eval_bare(...)
        4. |   +-base::tryCatch(...)
        5. |   | \-base (local) tryCatchList(expr, classes, parentenv, handlers)
        6. |   |   \-base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]])
        7. |   |     \-base (local) doTryCatch(return(expr), name, parentenv, handler)
        8. |   \-base::force(expr)
        9. \-rlang (local) f()
       10.   \-rlang (local) g()
       11.     \-rlang (local) <<CALL h(>><<CALL )>>

# namespaced calls are highlighted

    Code
      print_highlighted_trace(err)
    Output
      <error/rlang_error>
      Error in <<CALL `rlang:::as_string()`>>:
      ! Can't convert a double vector to a string.
      ---
      Backtrace:
           x
        1. +-rlang:::catch_error(f())
        2. | \-rlang::catch_cnd(expr, "error")
        3. |   +-rlang::eval_bare(...)
        4. |   +-base::tryCatch(...)
        5. |   | \-base (local) tryCatchList(expr, classes, parentenv, handlers)
        6. |   |   \-base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]])
        7. |   |     \-base (local) doTryCatch(return(expr), name, parentenv, handler)
        8. |   \-base::force(expr)
        9. \-rlang (local) f()
       10.   \-rlang (local) g()
       11.     \-rlang (local) h()
       12.       \-<<CALL rlang:::as_string(>>1<<CALL )>>

# can highlight long lists of arguments in backtrace (#1456)

    Code
      print_highlighted_trace(err)
    Output
      <error/rlang_error>
      Error in <<CALL `g()`>>:
      ! foo
      ---
      Backtrace:
           x
        1. +-rlang:::catch_error(f())
        2. | \-rlang::catch_cnd(expr, "error")
        3. |   +-rlang::eval_bare(...)
        4. |   +-base::tryCatch(...)
        5. |   | \-base (local) tryCatchList(expr, classes, parentenv, handlers)
        6. |   |   \-base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]])
        7. |   |     \-base (local) doTryCatch(return(expr), name, parentenv, handler)
        8. |   \-base::force(expr)
        9. \-rlang (local) f()
       10.   \-rlang (local) <<CALL g(>>...<<CALL )>>

---

    Code
      print_highlighted_trace(err)
    Output
      <error/rlang_error>
      Error in <<CALL `g()`>>:
      ! foo
      ---
      Backtrace:
           x
        1. +-rlang:::catch_error(f(arg = "bbbbbbbbbbbb"))
        2. | \-rlang::catch_cnd(expr, "error")
        3. |   +-rlang::eval_bare(...)
        4. |   +-base::tryCatch(...)
        5. |   | \-base (local) tryCatchList(expr, classes, parentenv, handlers)
        6. |   |   \-base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]])
        7. |   |     \-base (local) doTryCatch(return(expr), name, parentenv, handler)
        8. |   \-base::force(expr)
        9. \-rlang (local) f(arg = "bbbbbbbbbbbb")
       10.   \-rlang (local) <<CALL g(>><<ARG bbbbbbbbbbbb = bbbbbbbbbbbb>><<CALL )>>

# can highlight multi-line arguments in backtrace (#1456)

    Code
      print_highlighted_trace(err)
    Output
      <error/rlang_error>
      Error in <<CALL `g()`>>:
      ! foo
      ---
      Backtrace:
           x
        1. +-rlang:::catch_error(f())
        2. | \-rlang::catch_cnd(expr, "error")
        3. |   +-rlang::eval_bare(...)
        4. |   +-base::tryCatch(...)
        5. |   | \-base (local) tryCatchList(expr, classes, parentenv, handlers)
        6. |   |   \-base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]])
        7. |   |     \-base (local) doTryCatch(return(expr), name, parentenv, handler)
        8. |   \-base::force(expr)
        9. \-rlang (local) f()
       10.   \-rlang (local) <<CALL g(>>...<<CALL )>>

---

    Code
      print_highlighted_trace(err)
    Output
      <error/rlang_error>
      Error in <<CALL `g()`>>:
      ! foo
      ---
      Backtrace:
           x
        1. +-rlang:::catch_error(f(arg = "x"))
        2. | \-rlang::catch_cnd(expr, "error")
        3. |   +-rlang::eval_bare(...)
        4. |   +-base::tryCatch(...)
        5. |   | \-base (local) tryCatchList(expr, classes, parentenv, handlers)
        6. |   |   \-base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]])
        7. |   |     \-base (local) doTryCatch(return(expr), name, parentenv, handler)
        8. |   \-base::force(expr)
        9. \-rlang (local) f(arg = "x")
       10.   \-rlang (local) <<CALL g(>><<ARG x = { ... }>><<CALL )>>

