microsoft/onnxruntime-extensions

Public

mirrored from https://github.com/microsoft/onnxruntime-extensionsAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
0.14.0

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

include/exceptions.h

141lines · modeblame

5e44a7c3Scott McKay3 years ago1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the MIT License.
3
4#pragma once
5
6#if defined(__ANDROID__)
7#include <android/log.h>
8#else
9#include <iostream>
10#endif
11
12#include <stdexcept>
13
486c2b6dScott McKay2 years ago14// FUTURE: We need to do manual init in RegisterCustomOps to use the ORT C++ API
15// #ifdef OCOS_SHARED_LIBRARY
16// #define ORT_API_MANUAL_INIT
17// #include "onnxruntime_cxx_api.h"
18// #undef ORT_API_MANUAL_INIT
19// #else
20// #include "onnxruntime_cxx_api.h"
21// #endif
5e44a7c3Scott McKay3 years ago22#include "onnxruntime_c_api.h"
23
3b947b55Scott McKay2 years ago24// ORT_FILE is defined in the ORT C API from 1.15 on. Provide simplified definition for older versions.
25// On Windows, ORT_FILE is a wchar_t version of the __FILE__ macro.
26// Otherwise, ORT_FILE is equivalent to __FILE__.
27#ifndef ORT_FILE
28#ifdef _WIN32
29#define ORT_FILE __FILEW__
30#else
31#define ORT_FILE __FILE__
32#endif
33#endif
34
5e44a7c3Scott McKay3 years ago35namespace OrtW {
36
37// All C++ methods that can fail will throw an exception of this type
38struct Exception : std::exception {
39Exception(std::string message, OrtErrorCode code) : message_{std::move(message)}, code_{code} {}
40
41OrtErrorCode GetOrtErrorCode() const { return code_; }
42const char* what() const noexcept override { return message_.c_str(); }
43
44private:
45std::string message_;
46OrtErrorCode code_;
47};
48
486c2b6dScott McKay2 years ago49// helper that outputs an error message in a platform aware manner
50// Usages:
51// - logging exception message when they may not propagate up
52// - logging failure when using the ORT logger
53inline void LogError(const ORTCHAR_T* file, int line, const char* msg) {
5e44a7c3Scott McKay3 years ago54#if defined(__ANDROID__)
486c2b6dScott McKay2 years ago55__android_log_print(ANDROID_LOG_ERROR, "onnxruntime-extensions", "Error in %s line %d: %s", file, line, msg);
56#elif defined(_WIN32)
57// need to use wcerr as ORTCHAR_T is wchar_t on Windows
58std::wcerr << "Error in " << file << " line " << line << ": " << msg << std::endl;
5e44a7c3Scott McKay3 years ago59#else
486c2b6dScott McKay2 years ago60std::cerr << "Error in " << file << " line " << line << ": " << msg << std::endl;
5e44a7c3Scott McKay3 years ago61#endif
62}
63
64#ifdef OCOS_NO_EXCEPTIONS
486c2b6dScott McKay2 years ago65#define ORTX_CXX_API_THROW(msg, code) \
66do { \
67OrtW::LogError(ORT_FILE, __LINE__, OrtW::Exception(msg, code).what()); \
68abort(); \
5e44a7c3Scott McKay3 years ago69} while (false)
70
71#define OCOS_TRY if (true)
72#define OCOS_CATCH(x) else if (false)
73#define OCOS_RETHROW
74// In order to ignore the catch statement when a specific exception (not ... ) is caught and referred
75// in the body of the catch statements, it is necessary to wrap the body of the catch statement into
76// a lambda function. otherwise the exception referred will be undefined and cause build break
77#define OCOS_HANDLE_EXCEPTION(func)
78#else
486c2b6dScott McKay2 years ago79
80// if this is a shared library we need to throw a known exception type as onnxruntime will not know about
81// OrtW::Exception.
82#ifdef OCOS_SHARED_LIBRARY
83#if defined(__ANDROID__)
84// onnxruntime and extensions are built with a static libc++ so each has a different definition of
85// std::runtime_error, so the ORT output from catching this exception will be 'unknown exception' and the error
86// message is lost. log it first so at least it's somewhere
87#define ORTX_CXX_API_THROW(msg_in, code) \
88do { \
89std::string msg(msg_in); \
90OrtW::LogError(ORT_FILE, __LINE__, msg.c_str()); \
91throw std::runtime_error((std::to_string(code) + ": " + msg).c_str()); \
92} while (false)
93#else
94#define ORTX_CXX_API_THROW(msg, code) \
95throw std::runtime_error((std::to_string(code) + ": " + msg).c_str())
96#endif
97#else
98#define ORTX_CXX_API_THROW(msg, code) \
99throw OrtW::Exception(msg, code)
100#endif
5e44a7c3Scott McKay3 years ago101
102#define OCOS_TRY try
103#define OCOS_CATCH(x) catch (x)
104#define OCOS_RETHROW throw;
105#define OCOS_HANDLE_EXCEPTION(func) func()
106#endif
107
108inline void ThrowOnError(const OrtApi& ort, OrtStatus* status) {
109if (status) {
110std::string error_message = ort.GetErrorMessage(status);
111OrtErrorCode error_code = ort.GetErrorCode(status);
112ort.ReleaseStatus(status);
113ORTX_CXX_API_THROW(std::move(error_message), error_code);
114}
115}
116} // namespace OrtW
117
118// macros to wrap entry points that ORT calls where we may need to prevent exceptions propagating upwards to ORT
119#define OCOS_API_IMPL_BEGIN \
120OCOS_TRY {
121// if exceptions are disabled (a 3rd party library could throw so we need to handle that)
122// or we're preventing exception propagation, log and abort().
123#if defined(OCOS_NO_EXCEPTIONS) || defined(OCOS_PREVENT_EXCEPTION_PROPAGATION)
486c2b6dScott McKay2 years ago124#define OCOS_API_IMPL_END \
125} \
126OCOS_CATCH(const std::exception& ex) { \
127OCOS_HANDLE_EXCEPTION([&]() { \
128OrtW::LogError(ORT_FILE, __LINE__, ex.what()); \
129abort(); \
130}); \
5e44a7c3Scott McKay3 years ago131}
132#else
133// rethrow.
134#define OCOS_API_IMPL_END \
135} \
136OCOS_CATCH(const std::exception&) { \
137OCOS_HANDLE_EXCEPTION([&]() { \
138OCOS_RETHROW; \
139}); \
140}
141#endif