文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

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

2024-04-02 19:55

关注

本文讲述如何利用v8::TryCatch捕捉js代码中发生的异常。

首先,声明TryCatch对象。


v8::TryCatch trycatch( isolate );

然后,定义抛出异常的函数:


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 );
}

设置访问器访问C++函数:


v8::Local<v8::ObjectTemplate> 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<v8::Value> result = script->Run( context );
if ( trycatch.HasCaught() ) {
    v8::Local<v8::Message> 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 <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();

运行结果:

总结

本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注编程网的更多内容!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯