1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 /** 8 * A struct that encapsulates a JSContex and information about 9 * which binding method was called. The idea is to automatically annotate 10 * exceptions thrown via the BindingCallContext with the method name. 11 */ 12 13 #ifndef mozilla_dom_BindingCallContext_h 14 #define mozilla_dom_BindingCallContext_h 15 16 #include <utility> 17 18 #include "js/TypeDecls.h" 19 #include "mozilla/Assertions.h" 20 #include "mozilla/Attributes.h" 21 #include "mozilla/ErrorResult.h" 22 23 namespace mozilla { 24 namespace dom { 25 26 class MOZ_NON_TEMPORARY_CLASS MOZ_STACK_CLASS BindingCallContext { 27 public: 28 // aCx is allowed to be null. If it is, the BindingCallContext should 29 // generally act like a null JSContext*: test false when tested as a boolean 30 // and produce nullptr when used as a JSContext*. 31 // 32 // aMethodDescription should be something with longer lifetime than this 33 // BindingCallContext. Most simply, a string literal. nullptr or "" is 34 // allowed if we want to not have any particular message description. This 35 // argument corresponds to the "context" string used for DOM error codes that 36 // support one. See Errors.msg and the documentation for 37 // ErrorResult::MaybeSetPendingException for details on he context arg. BindingCallContext(JSContext * aCx,const char * aMethodDescription)38 BindingCallContext(JSContext* aCx, const char* aMethodDescription) 39 : mCx(aCx), mDescription(aMethodDescription) {} 40 41 ~BindingCallContext() = default; 42 43 // Allow passing a BindingCallContext as a JSContext*, as needed. 44 operator JSContext*() const { return mCx; } 45 46 // Allow testing a BindingCallContext for falsiness, just like a 47 // JSContext* could be tested. 48 explicit operator bool() const { return !!mCx; } 49 50 // Allow throwing an error message, if it has a context. 51 template <dom::ErrNum errorNumber, typename... Ts> ThrowErrorMessage(Ts &&...aMessageArgs)52 bool ThrowErrorMessage(Ts&&... aMessageArgs) const { 53 static_assert(ErrorFormatHasContext[errorNumber], 54 "We plan to add a context; it better be expected!"); 55 MOZ_ASSERT(mCx); 56 return dom::ThrowErrorMessage<errorNumber>( 57 mCx, mDescription, std::forward<Ts>(aMessageArgs)...); 58 } 59 60 private: 61 JSContext* const mCx; 62 const char* const mDescription; 63 }; 64 65 } // namespace dom 66 } // namespace mozilla 67 68 #endif // mozilla_dom_BindingCallContext_h 69