Skip to content

The promise you get from callBatch() remains pending indefinitely if you use an invalid executionType (which causes a disconnect) #358

Open
@eedefeed

Description

@eedefeed

Description

callBatch() returns a promise that should reject if an error occurs.

If you submit an invalid execution type, this causes a disconnect (presumably from OBS's side)
This library does not then settle the promise and it remains stuck in pending indefinitely.
Re-connecting does not result in the promise becoming settled.

The issue is reproducible using the 2 scripts provided. The first script uses setInterval() to show that the promise remains in pending and that neither the .then() and .catch() branches are not executed following the disconnect. The second scripts illustrates that re-connecting to OBS does not alleviate the problem.

Using the scripts:

  1. Change the url and pw parameters
  2. Create a media source called 'test track' in OBS.

If you need to match my configuration exactly, my media source is configured as follows:

loop: false
restart playback...: false
use hardware dec...: true
show nothing...: true
close file when...: true
speed: 100%
YUV colour range: Auto
apply alpha in lin....: false
FFmpeg Options: 

Versions

OBS version: 30.2.3
(from npm list) obs-websocket-js@5.0.6
node version: v20.9.0

Script 1

import { OBSWebSocket } from 'obs-websocket-js';

let url = 'ws://';
let pw = '';
let idParams = {rpcVersion: 1}

let inputName = "test track";


let obs = new OBSWebSocket();

// Connect
try {
    let conInfo = await obs.connect(url, pw, idParams);
    console.log(`Connected to OBS websockets ${conInfo.obsWebSocketVersion} (using RPC ${conInfo.negotiatedRpcVersion})`);
} catch (error) {
    console.error("[Error] Failed to connect to OBS websockets", error.code, error.message);
}

// Put error message in console when connection closed
obs.on("ConnectionClosed", (error) => {
    console.log("[Error] OBS connection closed event.", error);
});

try {
    let thePromise = obs.callBatch(
        [
            {
                requestType: "SetMediaInputCursor",
                requestData: {
                    inputName: inputName,
                    mediaCursor: 1000
                }
            },

            {
                requestType: "SetInputVolume",
                requestData: {
                    inputName: inputName,
                    inputVolumeDb: 80
                }
            }
        ],
        {
            haltOnFailure: true,
            executionType: 'RequestBatchExecutionType::SerialRealtime' //This is invalid and it's what causes websocket disconnect
        }
    );

    // show promise state in console
    setInterval((a)=>console.log(a), 1500, thePromise);

    const response = await thePromise;

    console.log("We never get here");
    console.log(response);

} catch (error) {
    
    console.log("we never get here either");
    console.log(error);

}

console.log("end");

Script 2 (reconnection)

import { OBSWebSocket } from 'obs-websocket-js';

let url = 'ws://';
let pw = '';
let idParams = {rpcVersion: 1}

let inputName = "test track";


let obs = new OBSWebSocket();

// Connect

async function connect(url, pw, idParams) {
    try {
        let conInfo = await obs.connect(url, pw, idParams);
        console.log(`Connected to OBS websockets ${conInfo.obsWebSocketVersion} (using RPC ${conInfo.negotiatedRpcVersion})`);
    } catch (error) {
        console.error('Failed to connect to OBS websockets', error.code, error.message);
    }
}

await connect(url, pw, idParams);

// Put error message in console when connection closed
obs.on("ConnectionClosed", (error) => {
    console.log("[Error] OBS connection closed event, re-attempting connection.", error);
    connect(url, pw, idParams);
});

try {
    let thePromise = obs.callBatch(
        [
            {
                requestType: "SetMediaInputCursor",
                requestData: {
                    inputName: inputName,
                    mediaCursor: 1000
                }
            },

            {
                requestType: "SetInputVolume",
                requestData: {
                    inputName: inputName,
                    inputVolumeDb: 80
                }
            }
        ],
        {
            haltOnFailure: true,
            executionType: 'RequestBatchExecutionType::SerialRealtime' //This is invalid and it's what causes websocket disconnect
        }
    );

    // show promise state in console
    setInterval((a)=>console.log(a), 1500, thePromise);

    const response = await thePromise;

    console.log("We never get here");
    console.log(response);

} catch (error) {
    
    console.log("we never get here either");
    console.log(error);

}

console.log("end");

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions