Advice for wrapping c++ library that throws exceptions?

I have a vendor library that throws exceptions, which makes wrapping them a bit more miserable. I only have access to headers and shared libraries, and I couldn’t figure out a way to link the libraries and prevent exceptions (it is probably impossible to prevent it).

Having the REPL abort because of an exception is not good, but wrapping the calls seems clunky (but at least it doesn’t abort). I was looking for anyone’s advice on how to handle this?

TLDR: I created a struct that had a boolean representing if the call was exception-free, and then a sequence of struct members representing the various forms of return types (crude sum type I guess) and then a const char * field that would contain the exception text. It sort of is okay-ish, but I would be glad to hear about anything more sleek.

Example C++ code
#include <cmath>
#include <exception>
#include <iostream>
#include <string>
#include <string.h>

constexpr size_t N = 2048;

extern "C" {

//------------------//
// notional library //
//------------------//
typedef struct Result {
    bool success;
    int as_int;
    double as_double;
    char what[N];
} Result;

double my_sqrt(double f) {
    if (f < 0.0)
        throw std::domain_error("negative value");
    return sqrt(f);
}

int add1(int f) {
    return f + 1;
}

//----------------------//
// notional wrapper API //
//----------------------//
Result my_sqrt_wrapper(double f) {
    Result ret;

    try {
        ret.as_double = my_sqrt(f);
        ret.success = true;
    } catch (const std::exception& e) {
        ret.success = false;
        strncpy(ret.what, e.what(), N);
        ret.what[N] = '\0';
    }

    return ret;
}

Result add1_wrapper(int f) {
    Result ret;

    try {
        ret.as_int = add1(f);
        ret.success = true;
    } catch (const std::exception& e) {
        ret.success = false;
        strncpy(ret.what, e.what(), N);
        ret.what[N] = '\0';
    }

    return ret;
}
Example Julia Wrapper
struct Result
    success::Cuchar
    as_int::Cint
    as_double::Cdouble
    what::NTuple{2048, Cchar}
end

function my_sqrt(x)
    a = @ccall "./libstuff.so".my_sqrt_wrapper(x::Cdouble)::Result
    if iszero(a.success)
        string_end = findfirst(iszero, a.what) - 1
        message = join(convert.(Char, a.what[1:string_end]))
        throw(DomainError(x, message))
    else
        a.as_double
    end
end

function add1(x)
    a = @ccall "./libstuff.so".add1_wrapper(x::Cint)::Result
    if iszero(a.success)
        string_end = findfirst(iszero, a.what) - 1
        message = join(convert.(Char, a.what[1:string_end]))
        throw(DomainError(x, message))
    else
        a.as_int
    end
end

@show add1(3)
@show my_sqrt(4)
@show my_sqrt(-4)