Skip to content

Commit

Permalink
fix(database): throw Error before creating promise
Browse files Browse the repository at this point in the history
Promises, even when resolved/rejected immediately after their creation, will
destroy any useful information from a stack trace when used over
events/exports.

Since some people still use the exports rather than MySQL/lib.lua, and for
some reason don't know the correct syntax for Lua exports (i.e. using
exports.oxmysql.query instead of the CORRECT exports.oxmysql:query) it's
comically common for an "untraceable" error to get spit out.

Will this help? No. Will everyone expect me to solve their issues? Yes.

Go update your scripts to use MySQL/lib.lua and we can all get along
stress-free.
  • Loading branch information
thelindat committed Nov 17, 2022
1 parent 30e37af commit 5a949b9
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 14 deletions.
15 changes: 10 additions & 5 deletions src/database/rawExecute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,31 @@ import { executeType, parseExecute } from '../utils/parseExecute';
import { scheduleTick } from '../utils/scheduleTick';
import { serverReady, waitForConnection } from '../database';

export const rawExecute = async (
export const rawExecute = (
invokingResource: string,
query: string,
parameters: CFXParameters,
cb?: CFXCallback,
throwError?: boolean
) => {
if (typeof query !== 'string')
throw new Error(
`${invokingResource} was unable to execute a query!\nExpected query to be a string but received ${typeof query} instead.`
);

const type = executeType(query);
const placeholders = query.split('?').length - 1;
parameters = parseExecute(placeholders, parameters);
if (parameters.length === 0) throw new Error(`Query received no parameters.`);
let response = [] as any;

if (!serverReady) await waitForConnection()

scheduleTick();

return await new Promise((resolve, reject) => {
return new Promise(async (resolve, reject) => {
if (!serverReady) await waitForConnection();

pool.getConnection((err, connection) => {
if (err) return reject(err.message);
if (parameters.length === 0) return reject(`Query received no parameters.`);

parameters.forEach((values, index) => {
const executionTime = process.hrtime();
Expand Down
13 changes: 9 additions & 4 deletions src/database/rawQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,25 @@ import type { CFXCallback, CFXParameters } from '../types';
import type { QueryType } from '../types';
import { scheduleTick } from '../utils/scheduleTick';

export const rawQuery = async (
export const rawQuery = (
type: QueryType,
invokingResource: string,
query: string,
parameters: CFXParameters,
cb?: CFXCallback,
throwError?: boolean
) => {
if (!serverReady) await waitForConnection()
if (typeof query !== 'string')
throw new Error(
`${invokingResource} was unable to execute a query!\nExpected query to be a string but received ${typeof query} instead.`
);

scheduleTick();
[query, parameters, cb] = parseArguments(invokingResource, query, parameters, cb);
scheduleTick();

return new Promise(async (resolve, reject) => {
if (!serverReady) await waitForConnection();

return await new Promise((resolve, reject) => {
pool.query(query, parameters, (err, result, _, executionTime) => {
if (err) return reject(err);

Expand Down
10 changes: 5 additions & 5 deletions src/utils/parseArguments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ export const parseArguments = (
parameters?: CFXParameters,
cb?: CFXCallback
): [string, CFXParameters, CFXCallback | undefined] => {
if (typeof query !== 'string') throw new Error(`Query expected a string but received ${typeof query} instead`);

if (convertNamedPlaceholders && parameters && typeof parameters === 'object' && !Array.isArray(parameters))
if (query.includes(':') || query.includes('@')) {
const placeholders = convertNamedPlaceholders(query, parameters);
Expand Down Expand Up @@ -42,9 +40,11 @@ export const parseArguments = (
if (diff > 0) {
for (let i = 0; i < diff; i++) parameters[queryParams.length + i] = null;
} else if (diff < 0) {
throw new Error(`${invokingResource} was unable to execute a query!
Expected ${queryParams.length} parameters, but received ${parameters.length}.
${`${query} ${JSON.stringify(parameters)}`}`);
throw new Error(
`${invokingResource} was unable to execute a query!\nExpected ${
queryParams.length
} parameters, but received ${parameters.length}.\n${`${query} ${JSON.stringify(parameters)}`}`
);
}
}
}
Expand Down

0 comments on commit 5a949b9

Please sign in to comment.