diff --git a/moto/cloudformation/exceptions.py b/moto/cloudformation/exceptions.py index a0a4eb63c..c8bb5b397 100644 --- a/moto/cloudformation/exceptions.py +++ b/moto/cloudformation/exceptions.py @@ -1,6 +1,26 @@ from __future__ import unicode_literals +from boto.exception import BotoServerError +from jinja2 import Template + class UnformattedGetAttTemplateException(Exception): description = 'Template error: resource {0} does not support attribute type {1} in Fn::GetAtt' status_code = 400 + + +class ValidationError(BotoServerError): + def __init__(self, name_or_id): + template = Template(STACK_DOES_NOT_EXIST_RESPONSE) + super(ValidationError, self).__init__(status=400, reason='Bad Request', + body=template.render(name_or_id=name_or_id)) + +STACK_DOES_NOT_EXIST_RESPONSE = """ + + Sender + ValidationError + Stack:{{ name_or_id }} does not exist + + cf4c737e-5ae2-11e4-a7c9-ad44eEXAMPLE + +""" diff --git a/moto/cloudformation/models.py b/moto/cloudformation/models.py index f54182174..3df740e66 100644 --- a/moto/cloudformation/models.py +++ b/moto/cloudformation/models.py @@ -5,6 +5,7 @@ from moto.core import BaseBackend from .parsing import ResourceMap, OutputMap from .utils import generate_stack_id +from .exceptions import ValidationError class FakeStack(object): @@ -50,10 +51,12 @@ class CloudFormationBackend(BaseBackend): for stack in stacks: if stack.name == name_or_stack_id or stack.stack_id == name_or_stack_id: return [stack] - deleted_stacks = self.deleted_stacks.values() - for stack in deleted_stacks: - if stack.stack_id == name_or_stack_id: - return [stack] + if self.deleted_stacks: + deleted_stacks = self.deleted_stacks.values() + for stack in deleted_stacks: + if stack.stack_id == name_or_stack_id: + return [stack] + raise ValidationError(name_or_stack_id) else: return stacks