mirror of
https://github.com/HeyPuter/puter.git
synced 2026-09-13 00:36:02 +00:00
feat: logging for queries in puter js
This commit is contained in:
+4
-1
@@ -43,4 +43,7 @@ jsconfig.json
|
||||
# node js
|
||||
# ======================================================================
|
||||
# the exact tree installed in the node_modules folder
|
||||
package-lock.json
|
||||
package-lock.json
|
||||
|
||||
AGENTS.md
|
||||
.roo
|
||||
+66
-24
@@ -1,31 +1,33 @@
|
||||
import OS from './modules/OS.js';
|
||||
import { PuterJSFileSystemModule } from './modules/FileSystem/index.js';
|
||||
import Hosting from './modules/Hosting.js';
|
||||
import Apps from './modules/Apps.js';
|
||||
import UI from './modules/UI.js';
|
||||
import KV from './modules/KV.js';
|
||||
import AI from './modules/AI.js';
|
||||
import Auth from './modules/Auth.js';
|
||||
import FSItem from './modules/FSItem.js';
|
||||
import * as utils from './lib/utils.js';
|
||||
import path from './lib/path.js';
|
||||
import Util from './modules/Util.js';
|
||||
import Drivers from './modules/Drivers.js';
|
||||
import putility from '@heyputer/putility';
|
||||
import { FSRelayService } from './services/FSRelay.js';
|
||||
import { FilesystemService } from './services/Filesystem.js';
|
||||
import { APIAccessService } from './services/APIAccess.js';
|
||||
import { XDIncomingService } from './services/XDIncoming.js';
|
||||
import { NoPuterYetService } from './services/NoPuterYet.js';
|
||||
import { Debug } from './modules/Debug.js';
|
||||
import { PSocket } from './modules/networking/PSocket.js';
|
||||
import { PTLSSocket } from "./modules/networking/PTLS.js"
|
||||
import Threads from './modules/Threads.js';
|
||||
import Perms from './modules/Perms.js';
|
||||
import { pFetch } from './modules/networking/requests.js';
|
||||
|
||||
import APICallLogger from './lib/APICallLogger.js';
|
||||
import path from './lib/path.js';
|
||||
import localStorageMemory from './lib/polyfills/localStorage.js'
|
||||
import xhrshim from './lib/polyfills/xhrshim.js'
|
||||
import * as utils from './lib/utils.js';
|
||||
import AI from './modules/AI.js';
|
||||
import Apps from './modules/Apps.js';
|
||||
import Auth from './modules/Auth.js';
|
||||
import { Debug } from './modules/Debug.js';
|
||||
import Drivers from './modules/Drivers.js';
|
||||
import { PuterJSFileSystemModule } from './modules/FileSystem/index.js';
|
||||
import FSItem from './modules/FSItem.js';
|
||||
import Hosting from './modules/Hosting.js';
|
||||
import KV from './modules/KV.js';
|
||||
import { PSocket } from './modules/networking/PSocket.js';
|
||||
import { PTLSSocket } from "./modules/networking/PTLS.js"
|
||||
import { pFetch } from './modules/networking/requests.js';
|
||||
import OS from './modules/OS.js';
|
||||
import Perms from './modules/Perms.js';
|
||||
import Threads from './modules/Threads.js';
|
||||
import UI from './modules/UI.js';
|
||||
import Util from './modules/Util.js';
|
||||
import { WorkersHandler } from './modules/Workers.js';
|
||||
import { APIAccessService } from './services/APIAccess.js';
|
||||
import { FilesystemService } from './services/Filesystem.js';
|
||||
import { FSRelayService } from './services/FSRelay.js';
|
||||
import { NoPuterYetService } from './services/NoPuterYet.js';
|
||||
import { XDIncomingService } from './services/XDIncoming.js';
|
||||
|
||||
// TODO: This is for a safe-guard below; we should check if we can
|
||||
// generalize this behavior rather than hard-coding it.
|
||||
@@ -255,6 +257,11 @@ export default globalThis.puter = (function() {
|
||||
cat: cat_logger,
|
||||
});
|
||||
|
||||
// Initialize API call logger
|
||||
this.apiCallLogger = new APICallLogger({
|
||||
enabled: false // Disabled by default
|
||||
});
|
||||
|
||||
// === START :: Services === //
|
||||
|
||||
this.services.register('no-puter-yet', NoPuterYetService);
|
||||
@@ -585,6 +592,41 @@ export default globalThis.puter = (function() {
|
||||
document.body.innerHTML += arg;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures API call logging settings
|
||||
* @param {Object} config - Configuration options for API call logging
|
||||
* @param {boolean} config.enabled - Enable/disable API call logging
|
||||
* @param {boolean} config.enabled - Enable/disable API call logging
|
||||
*/
|
||||
configureAPILogging = function(config = {}){
|
||||
if (this.apiCallLogger) {
|
||||
this.apiCallLogger.updateConfig(config);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables API call logging with optional configuration
|
||||
* @param {Object} config - Optional configuration to apply when enabling
|
||||
*/
|
||||
enableAPILogging = function(config = {}) {
|
||||
if (this.apiCallLogger) {
|
||||
this.apiCallLogger.updateConfig({ ...config, enabled: true });
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables API call logging
|
||||
*/
|
||||
disableAPILogging = function() {
|
||||
if (this.apiCallLogger) {
|
||||
this.apiCallLogger.disable();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Create a new Puter object and return it
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (C) 2024-present Puter Technologies Inc.
|
||||
*
|
||||
* This file is part of Puter.
|
||||
*
|
||||
* Puter is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* APICallLogger provides centralized logging for all API calls made by the puter-js SDK.
|
||||
* It logs API calls in a simple format: service - operation - params - result
|
||||
*/
|
||||
class APICallLogger {
|
||||
constructor(config = {}) {
|
||||
this.config = {
|
||||
enabled: config.enabled ?? false,
|
||||
...config
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the logger configuration
|
||||
* @param {Object} newConfig - New configuration options
|
||||
*/
|
||||
updateConfig(newConfig) {
|
||||
this.config = { ...this.config, ...newConfig };
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables API call logging
|
||||
*/
|
||||
enable() {
|
||||
this.config.enabled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables API call logging
|
||||
*/
|
||||
disable() {
|
||||
this.config.enabled = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if logging is enabled for the current configuration
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isEnabled() {
|
||||
return this.config.enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs the completion of an API request in a simple format
|
||||
* @param {Object} options - Request completion options
|
||||
*/
|
||||
logRequest(options = {}) {
|
||||
if (!this.isEnabled()) return;
|
||||
|
||||
const {
|
||||
service = 'unknown',
|
||||
operation = 'unknown',
|
||||
params = {},
|
||||
result = null,
|
||||
error = null
|
||||
} = options;
|
||||
|
||||
// Format params as a readable string
|
||||
let paramsStr = '{}';
|
||||
if (params && Object.keys(params).length > 0) {
|
||||
try {
|
||||
paramsStr = JSON.stringify(params);
|
||||
} catch (e) {
|
||||
paramsStr = '[Unable to serialize params]';
|
||||
}
|
||||
}
|
||||
|
||||
// Format the log message with bold params
|
||||
const logMessage = `${service} - ${operation} - \x1b[1m${paramsStr}\x1b[22m`;
|
||||
|
||||
if (error) {
|
||||
console.error(logMessage, { error: error.message || error, result });
|
||||
} else {
|
||||
console.log(logMessage, result);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets current logging statistics
|
||||
* @returns {Object}
|
||||
*/
|
||||
getStats() {
|
||||
return {
|
||||
enabled: this.config.enabled,
|
||||
config: { ...this.config }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export default APICallLogger;
|
||||
@@ -83,6 +83,17 @@ function initXhr(endpoint, APIOrigin, authToken, method= "post", contentType = "
|
||||
xhr.setRequestHeader("Authorization", "Bearer " + authToken);
|
||||
xhr.setRequestHeader("Content-Type", contentType);
|
||||
xhr.responseType = responseType ?? '';
|
||||
|
||||
// Add API call logging if available
|
||||
if (globalThis.puter?.apiCallLogger?.isEnabled()) {
|
||||
xhr._puterRequestId = {
|
||||
method,
|
||||
service: 'xhr',
|
||||
operation: endpoint.replace(/^\//, ''),
|
||||
params: { endpoint, contentType, responseType }
|
||||
};
|
||||
}
|
||||
|
||||
return xhr;
|
||||
}
|
||||
|
||||
@@ -160,12 +171,35 @@ function handle_error(error_cb, reject_func, error){
|
||||
|
||||
function setupXhrEventHandlers(xhr, success_cb, error_cb, resolve_func, reject_func) {
|
||||
// load: success or error
|
||||
xhr.addEventListener('load', function(e){
|
||||
xhr.addEventListener('load', async function(e){
|
||||
// Log the response if API logging is enabled
|
||||
if (globalThis.puter?.apiCallLogger?.isEnabled() && this._puterRequestId) {
|
||||
const response = await parseResponse(this).catch(() => null);
|
||||
globalThis.puter.apiCallLogger.logRequest({
|
||||
service: this._puterRequestId.service,
|
||||
operation: this._puterRequestId.operation,
|
||||
params: this._puterRequestId.params,
|
||||
result: this.status >= 400 ? null : response,
|
||||
error: this.status >= 400 ? { message: this.statusText, status: this.status } : null
|
||||
});
|
||||
}
|
||||
return handle_resp(success_cb, error_cb, resolve_func, reject_func, this, xhr);
|
||||
});
|
||||
|
||||
// error
|
||||
xhr.addEventListener('error', function(e){
|
||||
// Log the error if API logging is enabled
|
||||
if (globalThis.puter?.apiCallLogger?.isEnabled() && this._puterRequestId) {
|
||||
globalThis.puter.apiCallLogger.logRequest({
|
||||
service: this._puterRequestId.service,
|
||||
operation: this._puterRequestId.operation,
|
||||
params: this._puterRequestId.params,
|
||||
error: {
|
||||
message: 'Network error occurred',
|
||||
event: e.type
|
||||
}
|
||||
});
|
||||
}
|
||||
return handle_error(error_cb, reject_func, this);
|
||||
})
|
||||
}
|
||||
@@ -247,11 +281,32 @@ async function driverCall_(
|
||||
contentType = 'application/json;charset=UTF-8',
|
||||
settings = {},
|
||||
) {
|
||||
// Generate request ID for logging
|
||||
// Store request info for logging
|
||||
let requestInfo = null;
|
||||
if (globalThis.puter?.apiCallLogger?.isEnabled()) {
|
||||
requestInfo = {
|
||||
interface: driverInterface,
|
||||
driver: driverName,
|
||||
method: driverMethod,
|
||||
args: driverArgs
|
||||
};
|
||||
}
|
||||
|
||||
// If there is no authToken and the environment is web, try authenticating with Puter
|
||||
if(!puter.authToken && puter.env === 'web'){
|
||||
try{
|
||||
await puter.ui.authenticateWithPuter();
|
||||
}catch(e){
|
||||
// Log authentication error
|
||||
if (requestInfo && globalThis.puter?.apiCallLogger?.isEnabled()) {
|
||||
globalThis.puter.apiCallLogger.logRequest({
|
||||
service: 'drivers',
|
||||
operation: `${driverInterface}::${driverMethod}`,
|
||||
params: { interface: driverInterface, driver: driverName, method: driverMethod, args: driverArgs },
|
||||
error: { code: 'auth_canceled', message: 'Authentication canceled' }
|
||||
});
|
||||
}
|
||||
return reject_func({
|
||||
error: {
|
||||
code: 'auth_canceled', message: 'Authentication canceled'
|
||||
@@ -265,6 +320,11 @@ async function driverCall_(
|
||||
// create xhr object
|
||||
const xhr = initXhr('/drivers/call', puter.APIOrigin, puter.authToken, 'POST', contentType);
|
||||
|
||||
// Store request info for later logging
|
||||
if (requestInfo) {
|
||||
xhr._puterDriverRequestInfo = requestInfo;
|
||||
}
|
||||
|
||||
if ( settings.responseType ) {
|
||||
xhr.responseType = settings.responseType;
|
||||
}
|
||||
@@ -370,6 +430,18 @@ async function driverCall_(
|
||||
return;
|
||||
}
|
||||
const resp = await parseResponse(response.target);
|
||||
|
||||
// Log driver call response
|
||||
if (this._puterDriverRequestInfo && globalThis.puter?.apiCallLogger?.isEnabled()) {
|
||||
globalThis.puter.apiCallLogger.logRequest({
|
||||
service: 'drivers',
|
||||
operation: `${this._puterDriverRequestInfo.interface}::${this._puterDriverRequestInfo.method}`,
|
||||
params: { interface: this._puterDriverRequestInfo.interface, driver: this._puterDriverRequestInfo.driver, method: this._puterDriverRequestInfo.method, args: this._puterDriverRequestInfo.args },
|
||||
result: response.status >= 400 || resp?.success === false ? null : resp,
|
||||
error: response.status >= 400 || resp?.success === false ? resp : null
|
||||
});
|
||||
}
|
||||
|
||||
// HTTP Error - unauthorized
|
||||
if(response.status === 401 || resp?.code === "token_auth_failed"){
|
||||
if(resp?.code === "token_auth_failed" && puter.env === 'web'){
|
||||
@@ -436,6 +508,15 @@ async function driverCall_(
|
||||
|
||||
// error
|
||||
xhr.addEventListener('error', function(e){
|
||||
// Log driver call error
|
||||
if (this._puterDriverRequestInfo && globalThis.puter?.apiCallLogger?.isEnabled()) {
|
||||
globalThis.puter.apiCallLogger.logRequest({
|
||||
service: 'drivers',
|
||||
operation: `${this._puterDriverRequestInfo.interface}::${this._puterDriverRequestInfo.method}`,
|
||||
params: { interface: this._puterDriverRequestInfo.interface, driver: this._puterDriverRequestInfo.driver, method: this._puterDriverRequestInfo.method, args: this._puterDriverRequestInfo.args },
|
||||
error: { message: 'Network error occurred', event: e.type }
|
||||
});
|
||||
}
|
||||
return handle_error(error_cb, reject_func, this);
|
||||
})
|
||||
|
||||
|
||||
@@ -130,12 +130,41 @@ class Auth{
|
||||
}
|
||||
|
||||
async whoami () {
|
||||
const resp = await fetch(this.APIOrigin + '/whoami', {
|
||||
headers: {
|
||||
Authorization: `Bearer ${this.authToken}`
|
||||
try {
|
||||
const resp = await fetch(this.APIOrigin + '/whoami', {
|
||||
headers: {
|
||||
Authorization: `Bearer ${this.authToken}`
|
||||
}
|
||||
});
|
||||
|
||||
const result = await resp.json();
|
||||
|
||||
// Log the response
|
||||
if (globalThis.puter?.apiCallLogger?.isEnabled()) {
|
||||
globalThis.puter.apiCallLogger.logRequest({
|
||||
service: 'auth',
|
||||
operation: 'whoami',
|
||||
params: {},
|
||||
result: result
|
||||
});
|
||||
}
|
||||
});
|
||||
return await resp.json();
|
||||
|
||||
return result;
|
||||
} catch (error) {
|
||||
// Log the error
|
||||
if (globalThis.puter?.apiCallLogger?.isEnabled()) {
|
||||
globalThis.puter.apiCallLogger.logRequest({
|
||||
service: 'auth',
|
||||
operation: 'whoami',
|
||||
params: {},
|
||||
error: {
|
||||
message: error.message || error.toString(),
|
||||
stack: error.stack
|
||||
}
|
||||
});
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,34 +31,73 @@ class FetchDriverCallBackend {
|
||||
}
|
||||
|
||||
async call ({ driver, method_name, parameters }) {
|
||||
const resp = await fetch(`${this.context.APIOrigin}/drivers/call`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${this.context.authToken}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
'interface': driver.iface_name,
|
||||
...(driver.service_name
|
||||
? { service: driver.service_name }
|
||||
: {}),
|
||||
method: method_name,
|
||||
args: parameters,
|
||||
}),
|
||||
});
|
||||
|
||||
const content_type = resp.headers.get('content-type')
|
||||
.split(';')[0].trim(); // TODO: parser for Content-Type
|
||||
const handler = this.response_handlers[content_type];
|
||||
if ( ! handler ) {
|
||||
const msg = `unrecognized content type: ${content_type}`;
|
||||
console.error(msg);
|
||||
console.error('creating blob so dev tools shows response...');
|
||||
await resp.blob();
|
||||
throw new Error(msg);
|
||||
try {
|
||||
const resp = await fetch(`${this.context.APIOrigin}/drivers/call`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${this.context.authToken}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
'interface': driver.iface_name,
|
||||
...(driver.service_name
|
||||
? { service: driver.service_name }
|
||||
: {}),
|
||||
method: method_name,
|
||||
args: parameters,
|
||||
}),
|
||||
});
|
||||
|
||||
const content_type = resp.headers.get('content-type')
|
||||
.split(';')[0].trim(); // TODO: parser for Content-Type
|
||||
const handler = this.response_handlers[content_type];
|
||||
if ( ! handler ) {
|
||||
const msg = `unrecognized content type: ${content_type}`;
|
||||
console.error(msg);
|
||||
console.error('creating blob so dev tools shows response...');
|
||||
await resp.blob();
|
||||
|
||||
// Log the error
|
||||
if (globalThis.puter?.apiCallLogger?.isEnabled()) {
|
||||
globalThis.puter.apiCallLogger.logRequest({
|
||||
service: 'drivers',
|
||||
operation: `${driver.iface_name}::${method_name}`,
|
||||
params: { interface: driver.iface_name, driver: driver.service_name || driver.iface_name, method: method_name, args: parameters },
|
||||
error: { message: msg }
|
||||
});
|
||||
}
|
||||
|
||||
throw new Error(msg);
|
||||
}
|
||||
|
||||
const result = await handler(resp);
|
||||
|
||||
// Log the successful response
|
||||
if (globalThis.puter?.apiCallLogger?.isEnabled()) {
|
||||
globalThis.puter.apiCallLogger.logRequest({
|
||||
service: 'drivers',
|
||||
operation: `${driver.iface_name}::${method_name}`,
|
||||
params: { interface: driver.iface_name, driver: driver.service_name || driver.iface_name, method: method_name, args: parameters },
|
||||
result: result
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
} catch (error) {
|
||||
// Log unexpected errors
|
||||
if (globalThis.puter?.apiCallLogger?.isEnabled()) {
|
||||
globalThis.puter.apiCallLogger.logRequest({
|
||||
service: 'drivers',
|
||||
operation: `${driver.iface_name}::${method_name}`,
|
||||
params: { interface: driver.iface_name, driver: driver.service_name || driver.iface_name, method: method_name, args: parameters },
|
||||
error: {
|
||||
message: error.message || error.toString(),
|
||||
stack: error.stack
|
||||
}
|
||||
});
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
|
||||
return await handler(resp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,14 +176,42 @@ class Drivers {
|
||||
}
|
||||
|
||||
async list () {
|
||||
const resp = await fetch(`${this.APIOrigin}/lsmod`, {
|
||||
headers: {
|
||||
Authorization: 'Bearer ' + this.authToken,
|
||||
},
|
||||
method: 'POST'
|
||||
});
|
||||
const list = await resp.json();
|
||||
return list.interfaces;
|
||||
try {
|
||||
const resp = await fetch(`${this.APIOrigin}/lsmod`, {
|
||||
headers: {
|
||||
Authorization: 'Bearer ' + this.authToken,
|
||||
},
|
||||
method: 'POST'
|
||||
});
|
||||
|
||||
const list = await resp.json();
|
||||
|
||||
// Log the response
|
||||
if (globalThis.puter?.apiCallLogger?.isEnabled()) {
|
||||
globalThis.puter.apiCallLogger.logRequest({
|
||||
service: 'drivers',
|
||||
operation: 'list',
|
||||
params: {},
|
||||
result: list.interfaces
|
||||
});
|
||||
}
|
||||
|
||||
return list.interfaces;
|
||||
} catch (error) {
|
||||
// Log the error
|
||||
if (globalThis.puter?.apiCallLogger?.isEnabled()) {
|
||||
globalThis.puter.apiCallLogger.logRequest({
|
||||
service: 'drivers',
|
||||
operation: 'list',
|
||||
params: {},
|
||||
error: {
|
||||
message: error.message || error.toString(),
|
||||
stack: error.stack
|
||||
}
|
||||
});
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async get (iface_name, service_name) {
|
||||
|
||||
@@ -52,9 +52,20 @@ export function pFetch(...args) {
|
||||
parsedURL.port || 443,
|
||||
);
|
||||
} else {
|
||||
rej(
|
||||
`Failed to fetch. URL scheme "${parsedURL.protocol}" is not supported.`,
|
||||
);
|
||||
const errorMsg = `Failed to fetch. URL scheme "${parsedURL.protocol}" is not supported.`;
|
||||
|
||||
// Log the error
|
||||
if (globalThis.puter?.apiCallLogger?.isEnabled()) {
|
||||
globalThis.puter.apiCallLogger.logRequest({
|
||||
service: 'network',
|
||||
operation: 'pFetch',
|
||||
params: { url: reqObj.url, method: reqObj.method },
|
||||
error: { message: errorMsg }
|
||||
});
|
||||
}
|
||||
|
||||
rej(errorMsg);
|
||||
return;
|
||||
}
|
||||
|
||||
// Sending default UA
|
||||
@@ -198,6 +209,17 @@ export function pFetch(...args) {
|
||||
chunkedTransfer =
|
||||
parsedHead.headers.get("transfer-encoding") ===
|
||||
"chunked";
|
||||
|
||||
// Log the response
|
||||
if (globalThis.puter?.apiCallLogger?.isEnabled()) {
|
||||
globalThis.puter.apiCallLogger.logRequest({
|
||||
service: 'network',
|
||||
operation: 'pFetch',
|
||||
params: { url: reqObj.url, method: reqObj.method },
|
||||
result: { status: parsedHead.status, statusText: parsedHead.statusText }
|
||||
});
|
||||
}
|
||||
|
||||
// Return initial response object
|
||||
res(new Response(outStream, parsedHead));
|
||||
|
||||
@@ -232,11 +254,29 @@ export function pFetch(...args) {
|
||||
}
|
||||
});
|
||||
socket.on("error", (reason) => {
|
||||
// Log the error
|
||||
if (globalThis.puter?.apiCallLogger?.isEnabled()) {
|
||||
globalThis.puter.apiCallLogger.logRequest({
|
||||
service: 'network',
|
||||
operation: 'pFetch',
|
||||
params: { url: reqObj.url, method: reqObj.method },
|
||||
error: { message: "Socket errored with the following reason: " + reason }
|
||||
});
|
||||
}
|
||||
rej("Socket errored with the following reason: " + reason);
|
||||
});
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
// Log unexpected errors
|
||||
if (globalThis.puter?.apiCallLogger?.isEnabled()) {
|
||||
globalThis.puter.apiCallLogger.logRequest({
|
||||
service: 'network',
|
||||
operation: 'pFetch',
|
||||
params: { url: reqObj.url, method: reqObj.method },
|
||||
error: { message: e.message || e.toString(), stack: e.stack }
|
||||
});
|
||||
}
|
||||
rej(e);
|
||||
}});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user