/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ //! Functions to throw JavaScript exceptions from Rust. #![deny(missing_docs)] use jsapi::root::*; use libc; use std::ffi::CString; use std::{mem, os, ptr}; /// Format string used to throw javascript errors. static ERROR_FORMAT_STRING_STRING: [libc::c_char; 4] = [ '{' as libc::c_char, '0' as libc::c_char, '}' as libc::c_char, 0 as libc::c_char, ]; /// Format string struct used to throw `TypeError`s. static mut TYPE_ERROR_FORMAT_STRING: JSErrorFormatString = JSErrorFormatString { name: b"RUSTMSG_TYPE_ERROR\0" as *const _ as *const libc::c_char, format: &ERROR_FORMAT_STRING_STRING as *const libc::c_char, argCount: 1, exnType: JSExnType::JSEXN_TYPEERR as i16, }; /// Format string struct used to throw `RangeError`s. static mut RANGE_ERROR_FORMAT_STRING: JSErrorFormatString = JSErrorFormatString { name: b"RUSTMSG_RANGE_ERROR\0" as *const _ as *const libc::c_char, format: &ERROR_FORMAT_STRING_STRING as *const libc::c_char, argCount: 1, exnType: JSExnType::JSEXN_RANGEERR as i16, }; /// Callback used to throw javascript errors. /// See throw_js_error for info about error_number. unsafe extern "C" fn get_error_message( _user_ref: *mut os::raw::c_void, error_number: libc::c_uint, ) -> *const JSErrorFormatString { let num: JSExnType = mem::transmute(error_number); match num { JSExnType::JSEXN_TYPEERR => &TYPE_ERROR_FORMAT_STRING as *const JSErrorFormatString, JSExnType::JSEXN_RANGEERR => &RANGE_ERROR_FORMAT_STRING as *const JSErrorFormatString, _ => panic!( "Bad js error number given to get_error_message: {}", error_number ), } } /// Helper fn to throw a javascript error with the given message and number. /// Reuse the jsapi error codes to distinguish the error_number /// passed back to the get_error_message callback. /// c_uint is u32, so this cast is safe, as is casting to/from i32 from there. unsafe fn throw_js_error(cx: *mut JSContext, error: &str, error_number: u32) { let error = CString::new(error).unwrap(); JS_ReportErrorNumberUTF8( cx, Some(get_error_message), ptr::null_mut(), error_number, error.as_ptr(), ); } /// Throw a `TypeError` with the given message. pub unsafe fn throw_type_error(cx: *mut JSContext, error: &str) { throw_js_error(cx, error, JSExnType::JSEXN_TYPEERR as u32); } /// Throw a `RangeError` with the given message. pub unsafe fn throw_range_error(cx: *mut JSContext, error: &str) { throw_js_error(cx, error, JSExnType::JSEXN_RANGEERR as u32); }