JS调用C++函数抛出异常及捕捉异常详解

目录

  • 总结
本文讲述如何利用v8::TryCatch捕捉js代码中发生的异常。
首先,声明TryCatch对象。
v8::TryCatch trycatch( isolate );

然后,定义抛出异常的函数:
void ThrowException( const v8::FunctionCallbackInfo& info ) {v8::Isolate* isolate = info.GetIsolate(); v8::HandleScope scope( isolate ); v8::Local exc = v8::Local::New( info.GetIsolate(),v8::Exception::Error( v8::String::NewFromUtf8( isolate, "throw an exception" ).ToLocalChecked() ) ); info.GetIsolate()->ThrowException( exc ); }

设置访问器访问C++函数:
v8::Local global = v8::ObjectTemplate::New( isolate ); global->Set( isolate, "throwException",v8::FunctionTemplate::New( isolate, ThrowException ) );

因为异常发生在执行js文件期间,所以需要在Run函数后判断是否有异常发生。这里Run的结果没有继续调用ToLocalChecked(),因为result为NULL。
// Run the script to get the result.v8::MaybeLocal result = script->Run( context ); if ( trycatch.HasCaught() ) {v8::Local message = trycatch.Message(); ResolveMessage( message ); return -1; }

这样就可以在js文件中使用C++函数抛出异常,并解析异常信息。
main.cpp
// Copyright 2015 the V8 project authors. All rights reserved.// Use of this source code is governed by a BSD-style license that can be// found in the LICENSE file.#include #include #include #include "include/libplatform/libplatform.h"#include "include/v8.h"#include "point.h"using namespace std; using namespace v8; const std::string fileName = "file.js"; // Reads a file into a v8 string.MaybeLocal ReadFile( Isolate* isolate, const string& name ) {FILE* file = fopen( name.c_str(), "rb" ); if ( file == NULL ) return MaybeLocal(); fseek( file, 0, SEEK_END ); size_t size = ftell( file ); rewind( file ); std::unique_ptr chars( new char[size + 1] ); chars.get()[size] = '\0'; for ( size_t i = 0; i < size; ) {i += fread( &chars.get()[i], 1, size - i, file ); if ( ferror( file ) ) {fclose( file ); return MaybeLocal(); }}fclose( file ); MaybeLocal result = String::NewFromUtf8(isolate, chars.get(), NewStringType::kNormal, static_cast(size) ); return result; }void ThrowException( const v8::FunctionCallbackInfo& info ) {v8::Isolate* isolate = info.GetIsolate(); v8::HandleScope scope( isolate ); v8::Local exc = v8::Local::New( info.GetIsolate(),v8::Exception::Error( v8::String::NewFromUtf8( isolate, "throw an exception" ).ToLocalChecked() ) ); info.GetIsolate()->ThrowException( exc ); }void ResolveMessage( v8::Local message ) {v8::Isolate* isolate = message->GetIsolate(); v8::Local context = isolate->GetCurrentContext(); int lineNum = message->GetLineNumber( context ).ToChecked(); v8::String::Utf8Value err_msg( isolate, message->Get() ); v8::String::Utf8Value err_src( isolate, message->GetSourceLine( context ).ToLocalChecked() ); printf( "line %d, [error] %s, [error source] %s", lineNum, *err_msg, *err_src ); }int main( int argc, char* argv[] ) {// Initialize V8.v8::V8::InitializeICUDefaultLocation( argv[0] ); v8::V8::InitializeExternalStartupData( argv[0] ); std::unique_ptr platform = v8::platform::NewDefaultPlatform(); v8::V8::InitializePlatform( platform.get() ); v8::V8::Initialize(); // Create a new Isolate and make it the current one.v8::Isolate::CreateParams create_params; create_params.array_buffer_allocator =v8::ArrayBuffer::Allocator::NewDefaultAllocator(); v8::Isolate* isolate = v8::Isolate::New( create_params ); {v8::Isolate::Scope isolate_scope( isolate ); // Create a stack-allocated handle scope.v8::HandleScope handle_scope( isolate ); v8::TryCatch trycatch( isolate ); v8::Local global = v8::ObjectTemplate::New( isolate ); global->Set( isolate, "throwException",v8::FunctionTemplate::New( isolate, ThrowException ) ); // Create a new context.v8::Local context = v8::Context::New( isolate, nullptr, global ); // Enter the context for compiling and running the hello world script.v8::Context::Scope context_scope( context ); {// Create a string containing the JavaScript source code.v8::Local source; if ( !ReadFile( isolate, fileName ).ToLocal( &source ) ) {fprintf( stderr, "Error reading '%s'.\n", fileName.c_str() ); return -1; }// Compile the source code.v8::Local script =v8::Script::Compile( context, source ).ToLocalChecked(); // Run the script to get the result.v8::MaybeLocal result = script->Run( context ); if ( trycatch.HasCaught() ) {v8::Local message = trycatch.Message(); ResolveMessage( message ); return -1; }}}// Dispose the isolate and tear down V8.isolate->Dispose(); v8::V8::Dispose(); v8::V8::ShutdownPlatform(); delete create_params.array_buffer_allocator; return 0; }

file.js
throwException();

运行结果:
JS调用C++函数抛出异常及捕捉异常详解
文章图片


总结 【JS调用C++函数抛出异常及捕捉异常详解】本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注脚本之家的更多内容!

    推荐阅读