Skip to content

fix(esx_license): always answer the callback - #134

Open
seltonmt012 wants to merge 1 commit into
esx-framework:1.14.1from
seltonmt012:fix/license-callback-resolution
Open

fix(esx_license): always answer the callback#134
seltonmt012 wants to merge 1 commit into
esx-framework:1.14.1from
seltonmt012:fix/license-callback-resolution

Conversation

@seltonmt012

Copy link
Copy Markdown
Contributor

Description

Three server callbacks in esx_license only answer when they found an xPlayer. When they do not, the client waits forever.


Motivation

getLicense, getLicenses and checkLicense all call cb inside if xPlayer then. There is no else. When ESX.Player returns nil the handler simply ends, ESX.TriggerServerCallback on the client never resolves, and the player gets no menu, no error, and no hint that anything went wrong.

It is reachable without doing anything unusual. esx_boat, esx_weaponshop, esx_vehicleshop and esx_drugs all pass their own server id as the target:

ESX.TriggerServerCallback('esx_license:checkLicense', function(hasWeaponLicense)
    ...
end, ESX.serverId, 'weapon')

That id has no xPlayer yet during the loading window, and it has none while a character switch is in flight. Walk into the weapon shop at the wrong moment and the shop menu never opens.


Implementation Details

Each branch now answers with the same shape its success path uses, so consumers need no new handling:

callback success shape answer when the player is unknown
getLicense {type = ..., label = ...} nil
getLicenses query result list {}
checkLicense boolean false

false for checkLicense keeps a shop treating an unknown player as unlicensed, which is the branch every consumer already has, rather than leaving it hanging.

Driven against the shipped file with ESX.Player stubbed to nil:

callback before after
getLicense never fires cb(nil)
getLicenses never fires cb({})
checkLicense never fires cb(false)
getLicensesList cb(licenses) unchanged

getLicensesList never had the guard and is the control: identical in both runs.


Usage Example

-- during the loading window, before the player exists in ESX.Players
ESX.TriggerServerCallback('esx_license:checkLicense', function(hasLicense)
    -- before: this function is never called, the shop never opens
    -- after:  called with false, the player is offered the license menu
end, ESX.serverId, 'weapon')

PR Checklist

  • My commit messages and PR title follow the Conventional Commits standard.
  • My changes have been tested locally and function as expected.
  • My PR does not introduce any breaking changes.
  • I have provided a clear explanation of what my PR does, including the reasoning behind the changes and any relevant context.

Nothing that answered before answers differently. The three paths that changed previously returned nothing at all.

The plain AddEventHandler variants of the same names, further up the file, have the same gap. I left them alone because they are called with TriggerEvent from server code that passes a known id, so the failure mode there is not the same. Happy to fold them in if you would rather have both consistent.

getLicense, getLicenses and checkLicense only call cb inside the branch that
found an xPlayer. When ESX.Player returns nil the handler ends without ever
answering, and ESX.TriggerServerCallback on the client waits for a reply that
never comes. The player gets no menu, no error and no second chance until they
trigger the interaction again.

It is reachable: esx_boat, esx_weaponshop, esx_vehicleshop and esx_drugs all
pass their own server id as the target, and that id has no xPlayer yet during
the loading window or while a character switch is in flight.

Each branch now answers with the shape its success path uses: nil for the
single license, an empty list for getLicenses, and false for checkLicense, so
a shop keeps treating an unknown player as unlicensed instead of hanging.

Driven against the shipped file with ESX.Player stubbed to nil: before, the
three callbacks never fire. After, they answer cb(nil), cb({}) and cb(false).
getLicensesList never had the guard and is unchanged in both runs.
@seltonmt012
seltonmt012 force-pushed the fix/license-callback-resolution branch from 54e9a92 to ac1e880 Compare August 8, 2026 18:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant