Preheat Error after deploy - undefined local variable or method `cfn' for #<Jets::Preheat:>
Closed this issue ยท 9 comments
Checklist
- Upgrade Jets: Are you using the latest version of Jets? This allows Jets to fix issues fast. There's a
jets upgrade
command that makes this a simple task. There's also an Upgrading Guide: http://rubyonjets.com/docs/upgrading/ - Reproducibility: Are you reporting a bug others will be able to reproduce and not asking a question. If you're unsure or want to ask a question, do so on https://community.boltops.com
- Code sample: Have you put together a code sample to reproduce the issue and make it available? Code samples help speed up fixes dramatically. If it's an easily reproducible issue, then code samples are not needed. If you're unsure, please include a code sample.
My Environment
Software | Version |
---|---|
Operating System | public.ecr.aws/sam/build-ruby3.2:latest-arm64 |
Jets | 4.0.1 |
Ruby | 3.2 |
Expected Behavior
After upgrade to 4.0.1 from v3, I ran the jets deploy
command and expected the deploy to finish successfully.
Current Behavior
After UPDATE_COMPLETE, An error occurred when starting Preheat Job.
Step-by-step reproduction instructions
10:57:37AM DELETE_IN_PROGRESS AWS::Lambda::LayerVersion GemLayer
10:57:37AM UPDATE_COMPLETE AWS::CloudFormation::Stack ApiGateway
10:57:38AM DELETE_COMPLETE AWS::Lambda::LayerVersion GemLayer
10:57:38AM UPDATE_COMPLETE AWS::CloudFormation::Stack ***********
Stack success status: UPDATE_COMPLETE
Time took: 1m 23s
Prewarming application.
/var/lang/lib/ruby/gems/3.2.0/gems/jets-4.0.1/lib/jets/preheat.rb:94:in `all_functions': undefined local variable or method `cfn' for #<Jets::Preheat:0x0000ffffa2bc0cf8 @options={:mute=>true, :mute_output=>true, :invocation_type=>"Event", :lambda_proxy=>false}> (NameError)
parent_stack = cfn.describe_stack_resources(stack_name: Jets::Names.parent_stack_name)
^^^
from /var/lang/lib/ruby/gems/3.2.0/gems/memoist-0.16.2/lib/memoist.rb:169:in `all_functions'
from /var/lang/lib/ruby/gems/3.2.0/gems/jets-4.0.1/lib/jets/preheat.rb:32:in `warm_all'
from /var/lang/lib/ruby/gems/3.2.0/gems/jets-4.0.1/lib/jets/preheat.rb:15:in `warm_all'
from /var/lang/lib/ruby/gems/3.2.0/gems/jets-4.0.1/lib/jets/internal/app/jobs/jets/preheat_job.rb:51:in `warm'
from /var/lang/lib/ruby/gems/3.2.0/gems/jets-4.0.1/lib/jets/job/base.rb:31:in `perform_now'
from /var/lang/lib/ruby/gems/3.2.0/gems/jets-4.0.1/lib/jets/internal/app/jobs/jets/preheat_job.rb:59:in `prewarm!'
from /var/lang/lib/ruby/gems/3.2.0/gems/jets-4.0.1/lib/jets/cfn/ship.rb:108:in `prewarm'
from /var/lang/lib/ruby/gems/3.2.0/gems/jets-4.0.1/lib/jets/cfn/ship.rb:46:in `run'
from /var/lang/lib/ruby/gems/3.2.0/gems/jets-4.0.1/lib/jets/commands/deploy.rb:75:in `ship'
from /var/lang/lib/ruby/gems/3.2.0/gems/jets-4.0.1/lib/jets/commands/deploy.rb:36:in `run'
from /var/lang/lib/ruby/gems/3.2.0/gems/jets-4.0.1/lib/jets/commands/main.rb:27:in `deploy'
from /var/lang/lib/ruby/gems/3.2.0/gems/thor-1.2.2/lib/thor/command.rb:27:in `run'
from /var/lang/lib/ruby/gems/3.2.0/gems/thor-1.2.2/lib/thor/invocation.rb:127:in `invoke_command'
from /var/lang/lib/ruby/gems/3.2.0/gems/thor-1.2.2/lib/thor.rb:392:in `dispatch'
from /var/lang/lib/ruby/gems/3.2.0/gems/jets-4.0.1/lib/jets/commands/base.rb:38:in `dispatch'
from /var/lang/lib/ruby/gems/3.2.0/gems/jets-4.0.1/lib/jets/commands/base.rb:27:in `perform'
from /var/lang/lib/ruby/gems/3.2.0/gems/jets-4.0.1/lib/jets/cli.rb:28:in `start'
from /var/lang/lib/ruby/gems/3.2.0/gems/jets-4.0.1/lib/jets/cli.rb:5:in `start'
from /var/lang/lib/ruby/gems/3.2.0/gems/jets-4.0.1/exe/jets:14:in `<top (required)>'
from /var/lang/bin/jets:25:in `load'
from /var/lang/bin/jets:25:in `<main>'
Code Sample
nothing.
Solution Suggestion
nothing.
It looks like the fix for this is to add include Jets::AwsServices
to the Preheat class in preheat.rb
Snippet
module Jets
class Preheat
extend Memoist
include Jets::AwsServices # This fixes the reference to cfn
...
@NacchaF Thanks for the report
@dmorehouse Thanks for debugging and figuring out the issue
Feel free to do the honors of sending a PR. Or anyone else for that matter. Of course, no sweat either way ๐
I'm verifying my fix works and if it does I'll send over a PR.
Turns out this is more complicated than it originally looked. After adding include Jets::AwsServices
to the Preheat class. I now get the following error.
er.rb:41:in `delegate_guesser'
#<Thread:0x00007ff35482f0b0 /opt/ruby/gems/3.2.0/gems/jets-4.0.1/lib/jets/preheat.rb:36 run> terminated with exception (report_on_exception is true):
/opt/ruby/gems/3.2.0/gems/jets-4.0.1/lib/jets/commands/call/guesser.rb:30:in `class_name'
/opt/ruby/gems/3.2.0/gems/jets-4.0.1/lib/jets/commands/call.rb:87:in `ensure_guesses_found!'
/opt/ruby/gems/3.2.0/gems/jets-4.0.1/lib/jets/commands/call/guesser.rb:41:in `delegate_guesser': undefined method `=~' for #<struct Aws::CloudFormation::Types::StackResource stack_name="techbot-dev-JetsPublicController-62MKSS3H6CEM", stack_id="arn:aws:cloudformation:us-east-2:962773200528:stack/techbot-dev-JetsPublicController-62MKSS3H6CEM/2a40dc30-724f-11ed-89e4-0aef3ea0d208", logical_resource_id="ShowPermission", physical_resource_id="techbot-dev-JetsPublicController-62MKSS3H6CEM-ShowPermission-1NUI24P7P81SG", resource_type="AWS::Lambda::Permission", timestamp=2023-07-28 21:18:42.568 UTC, resource_status="UPDATE_COMPLETE", resource_status_reason=nil, description=nil, drift_information=#<struct Aws::CloudFormation::Types::StackResourceDriftInformation stack_resource_drift_status="NOT_CHECKED", last_check_timestamp=nil>, module_info=nil> (NoMethodError)
from /opt/ruby/gems/3.2.0/gems/jets-4.0.1/lib/jets/commands/call/guesser.rb:30:in `class_name'
from /opt/ruby/gems/3.2.0/gems/jets-4.0.1/lib/jets/commands/call.rb:87:in `ensure_guesses_found!'
from /opt/ruby/gems/3.2.0/gems/jets-4.0.1/lib/jets/commands/call.rb:21:in `function_name'
from /opt/ruby/gems/3.2.0/gems/jets-4.0.1/lib/jets/commands/call.rb:51:in `remote_run'
from /opt/ruby/gems/3.2.0/gems/jets-4.0.1/lib/jets/commands/call.rb:29:in `run'
from /opt/ruby/gems/3.2.0/gems/jets-4.0.1/lib/jets/preheat.rb:27:in `warm'
from /opt/ruby/gems/3.2.0/gems/jets-4.0.1/lib/jets/preheat.rb:37:in `block (2 levels) in warm_all'
/opt/ruby/gems/3.2.0/gems/jets-4.0.1/lib/jets/commands/call.rb:21:in `function_name'
/opt/ruby/gems/3.2.0/gems/jets-4.0.1/lib/jets/commands/call.rb:51:in `remote_run'
/opt/ruby/gems/3.2.0/gems/jets-4.0.1/lib/jets/commands/call.rb:29:in `run'
/opt/ruby/gems/3.2.0/gems/jets-4.0.1/lib/jets/preheat.rb:27:in `warm'
/opt/ruby/gems/3.2.0/gems/jets-4.0.1/lib/jets/preheat.rb:37:in `block (2 levels) in warm_all'
Critical exception from handler
{
"errorMessage": "undefined method `=~' for #<struct Aws::CloudFormation::Types::StackResource stack_name=\"techbot-dev-JetsPublicController-62MKSS3H6CEM\", stack_id=\"arn:aws:cloudformation:us-east-2:962773200528:stack/techbot-dev-JetsPublicController-62MKSS3H6CEM/2a40dc30-724f-11ed-89e4-0aef3ea0d208\", logical_resource_id=\"CatchallShowAnyApiMethod\", physical_resource_id=\"techb-Catch-SN2HLNOGS9NU\", resource_type=\"AWS::ApiGateway::Method\", timestamp=2023-07-28 21:18:42.925 UTC, resource_status=\"UPDATE_COMPLETE\", resource_status_reason=nil, description=nil, drift_information=#<struct Aws::CloudFormation::Types::StackResourceDriftInformation stack_resource_drift_status=\"NOT_CHECKED\", last_check_timestamp=nil>, module_info=nil>",
"errorType": "Function<NoMethodError>",
"stackTrace": [
"/opt/ruby/gems/3.2.0/gems/jets-4.0.1/lib/jets/commands/call/guesser.rb:41:in `delegate_guesser'",
"/opt/ruby/gems/3.2.0/gems/jets-4.0.1/lib/jets/commands/call/guesser.rb:30:in `class_name'",
"/opt/ruby/gems/3.2.0/gems/jets-4.0.1/lib/jets/commands/call.rb:87:in `ensure_guesses_found!'",
"/opt/ruby/gems/3.2.0/gems/jets-4.0.1/lib/jets/commands/call.rb:21:in `function_name'",
"/opt/ruby/gems/3.2.0/gems/jets-4.0.1/lib/jets/commands/call.rb:51:in `remote_run'",
"/opt/ruby/gems/3.2.0/gems/jets-4.0.1/lib/jets/commands/call.rb:29:in `run'",
"/opt/ruby/gems/3.2.0/gems/jets-4.0.1/lib/jets/preheat.rb:27:in `warm'",
"/opt/ruby/gems/3.2.0/gems/jets-4.0.1/lib/jets/preheat.rb:37:in `block (2 levels) in warm_all'"
@dmorehouse Oh I see. Ran into this in a WIP Jets v5 and fixed in it there. Unsure how long jets v5 is going to take. Maybe a few weeks out. So let's try backporting this fix.
I took the diff of master..v5 and adjusted it. Here's the relevant diff that should help. Haven't tested the specific diff below yet.
@@ -17,11 +17,13 @@ class Jets::Commands::Call
end
def function_name
- if @guess
+ if @provided_function_name.starts_with?(Jets.config.project_namespace)
+ @provided_function_name # fully qualified function name
+ elsif @guess
ensure_guesses_found! # possibly exits here
guesser.function_name # guesser adds namespace already
else
That should result in the function name lookup to be correct to the Jets#call
method, since the fully qualified name is already being passed in.
- https://github.com/boltops-tools/jets/blob/011e00dd157b25e6149e2a6d487e065184c9cecd/lib/jets/preheat.rb#L93
- https://github.com/boltops-tools/jets/blob/011e00dd157b25e6149e2a6d487e065184c9cecd/lib/jets/preheat.rb#L36
Maybe give that a try. Again, no sweat either way ๐ Thanks for your time.
@tongueroo I appreciate you taking the time to share the diff with me. Unfortunately, that change is a beyond my current comfort level with this project. I'll leave this to you or another first timer in this project. Again thanks for all your time.
All good! Thanks!
@tongueroo I took another try using your suggestion and it still failed. Debugging it looks like the problem moves to preheat.rb
all_functions
which is returning a struct not a function name. I get this error
undefined method 'starts_with?' for #<struct Aws::CloudFormation::Types::StackResource stack_name="techbot-dev-JetsPublicController-62MKSS3H6CEM", ...
You can see my implementation here - https://github.com/dmorehouse/jets/tree/fix-prewarming
Here's the full stacktrace from the Lambda console
gems/3.2.0/bundler/gems/jets-507332257644/lib/jets/commands/call.rb:31:in `run'
from /opt/ruby/gems/3.2.0/bundler/gems/jets-507332257644/lib/jets/preheat.rb:28:in `warm'
from /opt/ruby/gems/3.2.0/bundler/gems/jets-507332257644/lib/jets/preheat.rb:38:in `block (2 levels) in warm_all'
Calling warm for function: '#<struct Aws::CloudFormation::Types::StackResource stack_name="techbot-dev-JetsPublicController-62MKSS3H6CEM", stack_id="arn:aws:cloudformation:us-east-2:962773200528:stack/techbot-dev-JetsPublicController-62MKSS3H6CEM/2a40dc30-724f-11ed-89e4-0aef3ea0d208", logical_resource_id="ShowGetApiMethod", physical_resource_id="techb-ShowG-RFB23I5KXTZP", resource_type="AWS::ApiGateway::Method", timestamp=2023-07-28 21:18:42.986 UTC, resource_status="UPDATE_COMPLETE", resource_status_reason=nil, description=nil, drift_information=#<struct Aws::CloudFormation::Types::StackResourceDriftInformation stack_resource_drift_status="NOT_CHECKED", last_check_timestamp=nil>, module_info=nil>'
#<Thread:0x00007fd747286d08 /opt/ruby/gems/3.2.0/bundler/gems/jets-507332257644/lib/jets/preheat.rb:37 run> terminated with exception (report_on_exception is true):
/opt/ruby/gems/3.2.0/bundler/gems/jets-507332257644/lib/jets/commands/call.rb:20:in `function_name': undefined method `starts_with?' for #<struct Aws::CloudFormation::Types::StackResource stack_name="techbot-dev-JetsPublicController-62MKSS3H6CEM", stack_id="arn:aws:cloudformation:us-east-2:962773200528:stack/techbot-dev-JetsPublicController-62MKSS3H6CEM/2a40dc30-724f-11ed-89e4-0aef3ea0d208", logical_resource_id="ShowGetApiMethod", physical_resource_id="techb-ShowG-RFB23I5KXTZP", resource_type="AWS::ApiGateway::Method", timestamp=2023-07-28 21:18:42.986 UTC, resource_status="UPDATE_COMPLETE", resource_status_reason=nil, description=nil, drift_information=#<struct Aws::CloudFormation::Types::StackResourceDriftInformation stack_resource_drift_status="NOT_CHECKED", last_check_timestamp=nil>, module_info=nil> (NoMethodError)
if @provided_function_name.starts_with?(Jets.config.project_namespace)
^^^^^^^^^^^^^
from /opt/ruby/gems/3.2.0/bundler/gems/jets-507332257644/lib/jets/commands/call.rb:53:in `remote_run'
from /opt/ruby/gems/3.2.0/bundler/gems/jets-507332257644/lib/jets/commands/call.rb:31:in `run'
from /opt/ruby/gems/3.2.0/bundler/gems/jets-507332257644/lib/jets/preheat.rb:28:in `warm'
from /opt/ruby/gems/3.2.0/bundler/gems/jets-507332257644/lib/jets/preheat.rb:38:in `block (2 levels) in warm_all'
Critical exception from handler
{
"errorMessage": "undefined method `starts_with?' for #<struct Aws::CloudFormation::Types::StackResource stack_name=\"techbot-dev-JetsPublicController-62MKSS3H6CEM\", stack_id=\"arn:aws:cloudformation:us-east-2:962773200528:stack/techbot-dev-JetsPublicController-62MKSS3H6CEM/2a40dc30-724f-11ed-89e4-0aef3ea0d208\", logical_resource_id=\"CatchallShowAnyApiMethod\", physical_resource_id=\"techb-Catch-SN2HLNOGS9NU\", resource_type=\"AWS::ApiGateway::Method\", timestamp=2023-07-28 21:18:42.925 UTC, resource_status=\"UPDATE_COMPLETE\", resource_status_reason=nil, description=nil, drift_information=#<struct Aws::CloudFormation::Types::StackResourceDriftInformation stack_resource_drift_status=\"NOT_CHECKED\", last_check_timestamp=nil>, module_info=nil>",
"errorType": "Function<NoMethodError>",
"stackTrace": [
"/opt/ruby/gems/3.2.0/bundler/gems/jets-507332257644/lib/jets/commands/call.rb:20:in `function_name'",
"/opt/ruby/gems/3.2.0/bundler/gems/jets-507332257644/lib/jets/commands/call.rb:53:in `remote_run'",
"/opt/ruby/gems/3.2.0/bundler/gems/jets-507332257644/lib/jets/commands/call.rb:31:in `run'",
"/opt/ruby/gems/3.2.0/bundler/gems/jets-507332257644/lib/jets/preheat.rb:28:in `warm'",
"/opt/ruby/gems/3.2.0/bundler/gems/jets-507332257644/lib/jets/preheat.rb:38:in `block (2 levels) in warm_all'"
]
}
@dmorehouse Thanks for the debugging and commits. Merged your branch into this #660 PR and fixed function_names call that was causing the error you posted above.