• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

hanazuki / node-jsonnet / 26996766699

05 Jun 2026 05:12AM UTC coverage: 67.174% (-1.2%) from 68.343%
26996766699

Pull #450

github

web-flow
Merge ff878e3c1 into f13e4686e
Pull Request #450: check error from TSFN.BlockingCall

360 of 752 branches covered (47.87%)

Branch coverage included in aggregate %.

2 of 5 new or added lines in 1 file covered. (40.0%)

567 of 628 relevant lines covered (90.29%)

226.41 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

42.16
/src/Callback.hpp
1
// SPDX-License-Identifier: MIT
2
#pragma once
3

4
#include <exception>
5
#include <future>
6
#include <memory>
7
#include <stdexcept>
8
#include <napi.h>
9

10
#include "JsonnetVm.hpp"
11

12
namespace nodejsonnet {
13

14
  template <typename Result> struct CallbackPayload {
15
    explicit CallbackPayload(std::shared_ptr<JsonnetVm> vm): vm{std::move(vm)} {
204!
16
    }
204✔
17

18
    void setResult(Result value) {
148✔
19
      result.set_value(std::move(value));
148✔
20
    }
148✔
21
    void setError(std::exception_ptr e) {
56✔
22
      result.set_exception(e);
56!
23
    }
56✔
24
    std::future<Result> getFuture() {
204✔
25
      return result.get_future();
204✔
26
    }
27

28
  protected:
29
    std::shared_ptr<JsonnetVm> getVm() const {
272✔
30
      return vm;
272✔
31
    }
32

33
  private:
34
    std::shared_ptr<JsonnetVm> vm;
35
    std::promise<Result> result;
36
  };
37

38
  template <typename PayloadType> class Callback {
39
  public:
40
    Callback(Napi::Env env, Napi::Function fun)
380✔
41
      : tsfn{ThreadSafeFunction::New(env, fun, PayloadType::resourceName, 0, 1)} {
380✔
42
    }
380✔
43

44
    ~Callback() {
380✔
45
      tsfn.Release();
380!
46
    }
380✔
47

48
    Callback(Callback const &) = delete;
49
    Callback &operator=(Callback const &) = delete;
50

51
    template <typename... Args> auto call(std::shared_ptr<JsonnetVm> vm, Args &&...args) {
204✔
52
      // This function runs in a worker thread and cannot access Node VM.
53
      PayloadType payload(std::move(vm), std::forward<Args>(args)...);
204!
54
      auto const status = tsfn.BlockingCall(&payload);
204!
55
      if(status != napi_ok) {
204!
NEW
56
        throw std::runtime_error(
×
NEW
57
          std::string("ThreadSafeFunction::BlockingCall failed: napi_status=") +
×
NEW
58
          std::to_string(status));
×
59
      }
60
      return payload.getFuture().get();
204!
61
    }
260✔
62

63
  private:
64
    static void callback(
204✔
65
      Napi::Env env, Napi::Function fun, std::nullptr_t *, PayloadType *payload) {
66
      // This function runs in the Node main thread.
67
      try {
68
        auto const result = fun.Call(payload->makeArgs(env));
204!
69

70
        if(!result.IsPromise()) {
204!
71
          payload->resolveResult(result);
×
72
          return;
×
73
        }
74

75
        auto const on_success = Napi::Function::New(
408!
76
          env,
204✔
77
          [](Napi::CallbackInfo const &info) {
168✔
78
            auto const p = static_cast<PayloadType *>(info.Data());
168✔
79
            try {
80
              p->resolveResult(info[0]);
168!
81
            } catch(Napi::Error const &e) {
168!
82
              p->setError(std::make_exception_ptr(std::runtime_error(e.Message())));
20!
83
            } catch(...) {
20!
84
              p->setError(std::current_exception());
×
85
            }
20!
86
          },
188✔
87
          "onSuccess", payload);
204✔
88

89
        auto const on_failure = Napi::Function::New(
408!
90
          env,
204✔
91
          [](Napi::CallbackInfo const &info) {
36✔
92
            auto const p = static_cast<PayloadType *>(info.Data());
36✔
93
            try {
94
              auto const error = info[0].ToString();
36!
95
              p->setError(std::make_exception_ptr(std::runtime_error(error)));
36!
96
            } catch(Napi::Error const &e) {
36!
97
              p->setError(std::make_exception_ptr(std::runtime_error(e.Message())));
×
98
            } catch(...) {
×
99
              p->setError(std::current_exception());
×
100
            }
×
101
          },
36✔
102
          "onFailure", payload);
204✔
103

104
        result.template As<Napi::Promise>().Then(on_success, on_failure);
204!
105
      } catch(Napi::Error const &e) {
204!
106
        payload->setError(std::make_exception_ptr(std::runtime_error(e.Message())));
×
107
      } catch(...) {
×
108
        payload->setError(std::current_exception());
×
109
      }
×
110
    }
204✔
111

112
    using ThreadSafeFunction = Napi::TypedThreadSafeFunction<std::nullptr_t, PayloadType, callback>;
113
    ThreadSafeFunction tsfn;
114
  };
115

116
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc