godotengine / godotengine/godot
`load()` returns `GDScript` even with `Parse error`, but `new()` method can't be called and error is undetectable
- Dominant language
- C++
- Stars
- 117k
- Forks
- 26.8k
- PR merge metrics
- PR metrics pending
Description
### Tested versions
v4.2.1.stable.official [b09f793f5]
v4.3.stable.official [77dcf97d8]
### System information
Godot v4.2.1.stable
### Issue description
When loading a `.gd` script using the `load()` function in Godot, the function returns a `GDScript` object even if there are parsing errors in the script. This is unexpected because:
- A valid `GDScript` object should always have a `new()` method.
- Despite `loaded.has_method("new")` returning `true`, calling `loaded.new()` results in the error:
```
Invalid call. Nonexistent function 'new' in base 'GDScript'.
```
This issue is problematic because there's no clear way to detect or handle this scenario programmatically. Even with parse errors, the script loads and appears valid according to the checks. The only way to detect that the script has issues is by using `loaded.reload()`, which returns a non-zero value if errors are present. However, relying on this method for error detection is not intuitive or well-documented.
### Expected behavior:
- If there are parsing errors, load() should return null or provide a clear and intuitive way to detect errors.
- A valid GDScript should always have a new() method that can be called without errors.
### Steps to reproduce
Here’s an example of the code and its output in both normal and error scenarios:
### Code:
```gdscript
# res://main.gd
var loaded = load("res://error.gd")
print("loaded: ", loaded)
print("loaded == null: ", loaded == null)
print("loaded is GDScript: ", loaded is GDScript)
print("loaded.has_method('new'): ", loaded.has_method("new"))
print("loaded.new: ", loaded.new)
print("loaded.has_source_code(): ", loaded.has_source_code())
print("loaded.reload(): ", loaded.reload())
loaded.new()
```
```gdscript
# res://error.gd
error
```
### Output with a valid script:
```
loaded:
loaded == null: false
loaded is GDScript: true
loaded.has_method('new'): true
loaded.new: GDScript::new
loaded.has_source_code(): true
loaded.reload(): 0
```
### Output with a script containing parse errors:
```
loaded:
loaded == null: false
loaded is GDScript: true
loaded.has_method('new'): true
loaded.new: GDScript::new
loaded.has_source_code(): true
loaded.reload(): 43
```
### Error encountered:
```
Invalid call. Nonexistent function 'new' in base 'GDScript'.
```
### Steps to reproduce:
1. Use the code provided above to load a script and check its validity.
2. Create a .gd script with syntax errors and attempt to load it.
3. Observe that loaded.has_method("new") returns true, but calling loaded.new() raises an error.
4. Note that loaded.reload() returns a non-zero value, indicating an error that isn't detectable by other checks.
### Minimal reproduction project (MRP)
[gdscript load issue project.zip](https://github.com/user-attachments/files/16739816/gdscript.load.issue.project.zip)
Contributor guide
Assessment
This issue has not been assessed yet.