Skip to content

Commit 214f940

Browse files
authored
Merge pull request #2548 from markjmiller/markmiller/2516
Better error messages on plugin gem file upload #2516
2 parents 0706d53 + e6507b4 commit 214f940

File tree

3 files changed

+28
-1
lines changed

3 files changed

+28
-1
lines changed

openc3-cosmos-cmd-tlm-api/app/controllers/plugins_controller.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ def create(update = false)
101101
result = OpenC3::PluginModel.install_phase1(gem_file_path, store_id: params[:store_id], scope: scope)
102102
end
103103
render json: result
104+
rescue OpenC3::EmptyGemFileError => error
105+
render json: { status: 'error', message: error.message }, status: 400
106+
logger.error(error.formatted)
104107
rescue Exception => error
105108
render json: { status: 'error', message: error.message }, status: 500
106109
logger.error(error.formatted)

openc3-cosmos-cmd-tlm-api/spec/controllers/plugins_controller_spec.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,24 @@
165165
expect(json["message"]).to eq("Installation failed")
166166
end
167167

168+
it "returns bad request when gem file is empty" do
169+
allow(OpenC3::PluginModel).to receive(:install_phase1).and_raise(OpenC3::EmptyGemFileError.new("Gem file is empty: test-plugin.gem"))
170+
171+
post :create, params: { plugin: @upload_file, scope: "DEFAULT" }
172+
expect(response).to have_http_status(:bad_request)
173+
json = JSON.parse(response.body)
174+
expect(json["status"]).to eq("error")
175+
expect(json["message"]).to eq("Gem file is empty: test-plugin.gem")
176+
end
177+
178+
it "raises EmptyGemFileError when gem file is empty" do
179+
Tempfile.create(["empty-plugin", ".gem"]) do |tf|
180+
expect {
181+
OpenC3::PluginModel.install_phase1(tf.path, scope: "DEFAULT")
182+
}.to raise_error(OpenC3::EmptyGemFileError, /Gem file is empty/)
183+
end
184+
end
185+
168186
it "cleans up temporary directory on success" do
169187
allow(OpenC3::PluginModel).to receive(:install_phase1).and_return({})
170188
expect(FileUtils).to receive(:remove_entry_secure).with("/tmp/test", true)

openc3/lib/openc3/models/plugin_model.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
require 'fileutils'
4242

4343
module OpenC3
44+
class EmptyGemFileError < StandardError; end
45+
4446
# Represents a OpenC3 plugin that can consist of targets, interfaces, routers
4547
# microservices and tools. The PluginModel installs all these pieces as well
4648
# as destroys them all when the plugin is removed.
@@ -87,6 +89,10 @@ def self.install_phase1(gem_file_path, existing_variables: nil, existing_plugin_
8789
tf = nil
8890
begin
8991
if File.exist?(gem_file_path)
92+
if File.zero?(gem_file_path)
93+
raise EmptyGemFileError, "Gem file is empty: #{gem_file_path}"
94+
end
95+
9096
# Load gem to internal gem server
9197
OpenC3::GemModel.put(gem_file_path, gem_install: false, scope: scope) unless validate_only
9298
else
@@ -209,7 +215,7 @@ def self.install_phase2(plugin_hash, scope:, gem_file_path: nil, validate_only:
209215
# Handle python dependencies (pyproject.toml or requirements.txt)
210216
pyproject_path = File.join(gem_path, 'pyproject.toml')
211217
requirements_path = File.join(gem_path, 'requirements.txt')
212-
218+
213219
if File.exist?(pyproject_path) || File.exist?(requirements_path)
214220
begin
215221
pypi_url = get_setting('pypi_url', scope: scope)

0 commit comments

Comments
 (0)