JS調(diào)用C++函數(shù)拋出異常及捕捉異常詳解
本文講述如何利用v8::TryCatch捕捉j(luò)s代碼中發(fā)生的異常。
首先,聲明TryCatch對象。
v8::TryCatch trycatch( isolate );
然后,定義拋出異常的函數(shù):
void ThrowException( const v8::FunctionCallbackInfo<v8::Value>& info ) {
v8::Isolate* isolate = info.GetIsolate();
v8::HandleScope scope( isolate );
v8::Local<v8::Value> exc = v8::Local<v8::Value>::New( info.GetIsolate(),
v8::Exception::Error( v8::String::NewFromUtf8( isolate, "throw an exception" ).ToLocalChecked() ) );
info.GetIsolate()->ThrowException( exc );
}
設(shè)置訪問器訪問C++函數(shù):
v8::Local<v8::ObjectTemplate> global = v8::ObjectTemplate::New( isolate );
global->Set( isolate, "throwException",
v8::FunctionTemplate::New( isolate, ThrowException ) );
因?yàn)楫惓0l(fā)生在執(zhí)行js文件期間,所以需要在Run函數(shù)后判斷是否有異常發(fā)生。這里Run的結(jié)果沒有繼續(xù)調(diào)用ToLocalChecked(),因?yàn)閞esult為NULL。
// Run the script to get the result.
v8::MaybeLocal<v8::Value> result = script->Run( context );
if ( trycatch.HasCaught() ) {
v8::Local<v8::Message> message = trycatch.Message();
ResolveMessage( message );
return -1;
}
這樣就可以在js文件中使用C++函數(shù)拋出異常,并解析異常信息。
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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#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<String> ReadFile( Isolate* isolate, const string& name ) {
FILE* file = fopen( name.c_str(), "rb" );
if ( file == NULL ) return MaybeLocal<String>();
fseek( file, 0, SEEK_END );
size_t size = ftell( file );
rewind( file );
std::unique_ptr<char> 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<String>();
}
}
fclose( file );
MaybeLocal<String> result = String::NewFromUtf8(
isolate, chars.get(), NewStringType::kNormal, static_cast<int>(size) );
return result;
}
void ThrowException( const v8::FunctionCallbackInfo<v8::Value>& info ) {
v8::Isolate* isolate = info.GetIsolate();
v8::HandleScope scope( isolate );
v8::Local<v8::Value> exc = v8::Local<v8::Value>::New( info.GetIsolate(),
v8::Exception::Error( v8::String::NewFromUtf8( isolate, "throw an exception" ).ToLocalChecked() ) );
info.GetIsolate()->ThrowException( exc );
}
void ResolveMessage( v8::Local<v8::Message> message ) {
v8::Isolate* isolate = message->GetIsolate();
v8::Local<v8::Context> 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<v8::Platform> 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<v8::ObjectTemplate> global = v8::ObjectTemplate::New( isolate );
global->Set( isolate, "throwException",
v8::FunctionTemplate::New( isolate, ThrowException ) );
// Create a new context.
v8::Local<v8::Context> 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<v8::String> source;
if ( !ReadFile( isolate, fileName ).ToLocal( &source ) ) {
fprintf( stderr, "Error reading '%s'.\n", fileName.c_str() );
return -1;
}
// Compile the source code.
v8::Local<v8::Script> script =
v8::Script::Compile( context, source ).ToLocalChecked();
// Run the script to get the result.
v8::MaybeLocal<v8::Value> result = script->Run( context );
if ( trycatch.HasCaught() ) {
v8::Local<v8::Message> 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();
運(yùn)行結(jié)果:

總結(jié)
本篇文章就到這里了,希望能給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
關(guān)于C++的重載運(yùn)算符和重載函數(shù)
一般來說,重載運(yùn)算符在實(shí)際的項(xiàng)目開發(fā)中會經(jīng)常的用到,但如果某些自定義類型通過簡短幾行代碼重載一些常用的運(yùn)算符(如:+-*/),就能讓編程工作帶來方便,需要的朋友可以參考下本文2023-05-05
解析VC中創(chuàng)建DLL,導(dǎo)出全局變量,函數(shù)和類的深入分析
本篇文章是對VC中創(chuàng)建DLL,導(dǎo)出全局變量,函數(shù)和類進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
詳解C++設(shè)計模式編程中責(zé)任鏈模式的應(yīng)用
這篇文章主要介紹了C++設(shè)計模式編程中責(zé)任鏈模式的應(yīng)用,責(zé)任鏈模式使多個對象都有機(jī)會處理請求,從而避免請求的發(fā)送者和接收者之間的耦合關(guān)系,需要的朋友可以參考下2016-03-03
使用C語言順序表數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)棧的代碼示例
這篇文章主要給大家介紹了如何使用C語言順序表數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)棧,文章通過代碼示例介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的參考價值,需要的朋友可以參考下2023-09-09
深入解析C++的WNDCLASS結(jié)構(gòu)體及其在Windows中的應(yīng)用
這篇文章主要介紹了C++的WNDCLASS結(jié)構(gòu)體及其在Windows中的應(yīng)用,WNDCLASS被用來定義窗口,文中介紹了其諸多屬性,需要的朋友可以參考下2016-01-01

