-
Notifications
You must be signed in to change notification settings - Fork 66
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improve BGS validation error logging (#12939)
BGS sometimes returns errors containing an enormous stacktrace with an oracle error. This PR logs the oracle error message and excludes everything else. These oracle errors start with the signature `ORA-` and are bookended by a `prepstmnt` clause. See `spec/fixtures/bgs/bgs_oracle_error.txt` for an example. We want to log these errors separately because the original error message is so long that it obscures its only relevant information and actually breaks Sentry's UI.
- Loading branch information
Showing
3 changed files
with
199 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
(ns0:Server) EJB Exception: : <openjpa-1.1.1-SNAPSHOT-r422266:1445923 fatal general error> org.apache.openjpa.persistence.PersistenceException: The transaction has been rolled back. See the nested exceptions for details on the errors that occurred. | ||
at org.apache.openjpa.kernel.BrokerImpl.newFlushException(BrokerImpl.java:2170) | ||
at org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:2017) | ||
at org.apache.openjpa.kernel.BrokerImpl.flushSafe(BrokerImpl.java:1915) | ||
at org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:1686) | ||
at org.apache.openjpa.kernel.QueryImpl.isInMemory(QueryImpl.java:955) | ||
at org.apache.openjpa.kernel.QueryImpl.execute(QueryImpl.java:795) | ||
at org.apache.openjpa.kernel.QueryImpl.updateAll(QueryImpl.java:883) | ||
at kodo.kernel.KodoQuery.updateAll(KodoQuery.java:67) | ||
at org.apache.openjpa.kernel.QueryImpl.updateAll(QueryImpl.java:879) | ||
at kodo.kernel.KodoQuery.updateAll(KodoQuery.java:63) | ||
at org.apache.openjpa.kernel.DelegatingQuery.updateAll(DelegatingQuery.java:565) | ||
at org.apache.openjpa.persistence.QueryImpl.executeUpdate(QueryImpl.java:322) | ||
at sun.reflect.GeneratedMethodAccessor3781.invoke(Unknown Source) | ||
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) | ||
at java.lang.reflect.Method.invoke(Method.java:498) | ||
at weblogic.persistence.InterceptingInvocationHandlerImpl.invoke(InterceptingInvocationHandlerImpl.java:24) | ||
at com.sun.proxy.$Proxy879.executeUpdate(Unknown Source) | ||
at gov.va.vba.benefits.vdc.util.Util.clearDBGlobals(Unknown Source) | ||
at gov.va.vba.vonapp.services.personService.VnpPersonWebServiceBean.vnpPersonCreate(Unknown Source) | ||
at sun.reflect.GeneratedMethodAccessor6329.invoke(Unknown Source) | ||
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) | ||
at java.lang.reflect.Method.invoke(Method.java:498) | ||
at com.bea.core.repackaged.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) | ||
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) | ||
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) | ||
at com.oracle.pitchfork.intercept.MethodInvocationInvocationContext.proceed(MethodInvocationInvocationContext.java:101) | ||
at com.oracle.pitchfork.intercept.JeeInterceptorInterceptor.invoke(JeeInterceptorInterceptor.java:101) | ||
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) | ||
at com.oracle.pitchfork.intercept.MethodInvocationInvocationContext.proceed(MethodInvocationInvocationContext.java:101) | ||
at org.jboss.weld.ejb.AbstractEJBRequestScopeActivationInterceptor.aroundInvoke(AbstractEJBRequestScopeActivationInterceptor.java:73) | ||
at org.jboss.weld.ejb.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:52) | ||
at sun.reflect.GeneratedMethodAccessor449.invoke(Unknown Source) | ||
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) | ||
at java.lang.reflect.Method.invoke(Method.java:498) | ||
at com.oracle.pitchfork.intercept.JeeInterceptorInterceptor.invoke(JeeInterceptorInterceptor.java:94) | ||
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) | ||
at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:136) | ||
at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:124) | ||
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) | ||
at com.bea.core.repackaged.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) | ||
at com.sun.proxy.$Proxy928.vnpPersonCreate(Unknown Source) | ||
at gov.va.vba.vonapp.services.personService.VnpPersonWebServiceBean_mfemv4_WSOImpl.__WL_invoke(Unknown Source) | ||
at weblogic.ejb.container.internal.WSOMethodInvoker.invoke(WSOMethodInvoker.java:24) | ||
at gov.va.vba.vonapp.services.personService.VnpPersonWebServiceBean_mfemv4_WSOImpl.__WL_vnpPersonCreate_WS(Unknown Source) | ||
at sun.reflect.GeneratedMethodAccessor6328.invoke(Unknown Source) | ||
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) | ||
at java.lang.reflect.Method.invoke(Method.java:498) | ||
at weblogic.wsee.server.ejb.WsEjb.invoke(WsEjb.java:55) | ||
at weblogic.wsee.jaxws.WLSEjbInstanceResolver$WLSEjbInvoker.invoke(WLSEjbInstanceResolver.java:196) | ||
at weblogic.wsee.jaxws.WLSInstanceResolver$WLSInvoker.invoke(WLSInstanceResolver.java:93) | ||
at com.sun.xml.ws.server.InvokerTube$2.invoke(InvokerTube.java:149) | ||
at com.sun.xml.ws.server.sei.SEIInvokerTube.processRequest(SEIInvokerTube.java:88) | ||
at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:1136) | ||
at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:1050) | ||
at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:1019) | ||
at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:877) | ||
at com.sun.xml.ws.server.WSEndpointImpl$2.process(WSEndpointImpl.java:419) | ||
at com.sun.xml.ws.transport.http.HttpAdapter$HttpToolkit.handle(HttpAdapter.java:868) | ||
at com.sun.xml.ws.transport.http.HttpAdapter.handle(HttpAdapter.java:422) | ||
at com.sun.xml.ws.transport.http.servlet.ServletAdapter.handle(ServletAdapter.java:169) | ||
at weblogic.wsee.jaxws.WLSServletAdapter.handle(WLSServletAdapter.java:246) | ||
at weblogic.wsee.jaxws.HttpServletAdapter$AuthorizedInvoke.run(HttpServletAdapter.java:667) | ||
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:386) | ||
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:163) | ||
at weblogic.wsee.util.ServerSecurityHelper.authenticatedInvoke(ServerSecurityHelper.java:108) | ||
at weblogic.wsee.jaxws.HttpServletAdapter$3.run(HttpServletAdapter.java:286) | ||
at weblogic.wsee.jaxws.HttpServletAdapter.post(HttpServletAdapter.java:295) | ||
at weblogic.wsee.jaxws.JAXWSServlet.doRequest(JAXWSServlet.java:128) | ||
at weblogic.servlet.http.AbstractAsyncServlet.service(AbstractAsyncServlet.java:103) | ||
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) | ||
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:295) | ||
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:260) | ||
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:137) | ||
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:353) | ||
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:250) | ||
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3796) | ||
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3766) | ||
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:344) | ||
at weblogic.security.service.SecurityManager.runAsForUserCode(SecurityManager.java:197) | ||
at weblogic.servlet.provider.WlsSecurityProvider.runAsForUserCode(WlsSecurityProvider.java:203) | ||
at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:71) | ||
at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2454) | ||
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2302) | ||
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2280) | ||
at weblogic.servlet.internal.ServletRequestImpl.runInternal(ServletRequestImpl.java:1721) | ||
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1681) | ||
at weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.java:272) | ||
at weblogic.invocation.ComponentInvocationContextManager._runAs(ComponentInvocationContextManager.java:352) | ||
at weblogic.invocation.ComponentInvocationContextManager.runAs(ComponentInvocationContextManager.java:337) | ||
at weblogic.work.LivePartitionUtility.doRunWorkUnderContext(LivePartitionUtility.java:57) | ||
at weblogic.work.PartitionUtility.runWorkUnderContext(PartitionUtility.java:41) | ||
at weblogic.work.SelfTuningWorkManagerImpl.runWorkUnderContext(SelfTuningWorkManagerImpl.java:655) | ||
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:420) | ||
at weblogic.work.ExecuteThread.run(ExecuteThread.java:360) | ||
Caused by: <openjpa-1.1.1-SNAPSHOT-r422266:1445923 nonfatal general error> org.apache.openjpa.persistence.PersistenceException: ORA-12899: value too large for column "CORPPROD"."VNP_PERSON"."MIDDLE_NM" (actual: 52, maximum: 30) | ||
{prepstmnt 121207984 INSERT INTO VNP_PERSON (VNP_PTCPNT_ID, BIRTH_CITY_NM, BIRTH_CNTRY_NM, BIRTH_STATE_CD, BRTHDY_DT, CMPTNY_DECN_TYPE_CD, DEATH_CITY_CNTRY_NM, DEATH_CNTRY_NM, DEATH_DT, DEATH_STATE_CD, DEP_NBR, EMP_IND, ENTLMT_TYPE_CD, ETHNIC_TYPE_CD, EVER_MARIED_IND, FID_DECN_CATEGY_TYPE_CD, FILE_NBR, FIRST_NM, FIRST_NM_KEY, FRGN_SVC_NBR, GENDER_CD, JRN_DT, JRN_LCTN_ID, JRN_OBJ_ID, JRN_STATUS_TYPE_CD, JRN_USER_ID, LAST_NM, LAST_NM_KEY, LGY_ENTLMT_TYPE_CD, MARTL_STATUS_TYPE_CD, MIDDLE_NM, MIDDLE_NM_KEY, MLTY_PERSON_IND, MONTHS_PRESNT_EMPLYR_NBR, NET_WORTH_AMT, NO_SSN_REASON_TYPE_CD, OCPTN_TXT, PERSON_DEATH_CAUSE_TYPE_NM, PERSON_TYPE_NM, POTNTL_DNGRS_IND, RACE_TYPE_NM, SBSTNC_AMT, SEROUS_EMPLMT_HNDCAP_IND, SLTTN_TYPE_NM, SPINA_BIFIDA_IND, SPOUSE_NUM, SSN_NBR, SSN_VRFCTN_STATUS_TYPE_CD, SUFFIX_NM, SUFFIX_NM_KEY, TAX_ABTMNT_CD, TERMNL_DIGIT_NBR, TITLE_TXT, VET_IND, VET_TYPE_NM, VNP_PROC_ID, VNP_SCHOOL_CHILD_IND, VNP_SRUSLY_DSABLD_IND, YEARS_PRESNT_EMPLYR_NBR) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) [params=(long) 11111111, (String) Foo, (null) null, (String) HI, (Date) 2008-06-20, (null) null, (null) null, (null) null, (null) null, (null) null, (null) null, (null) null, (null) null, (null) null, (String) N, (null) null, (null) null, (String) Bar, (null) null, (null) null, (null) null, (Timestamp) 2023-05-16 00:00:00.0, (String) 281, (String) VAgovAPI, (String) U, (String) VAgovAPI, (String) Baz, (null) null, (null) null, (null) null, (String) Foo, (null) null, (null) null, (null) null, (null) null, (null) null, (null) null, (null) null, (null) null, (null) null, (null) null, (null) null, (null) null, (null) null, (null) null, (null) null, (String) 11111111, (null) null, (null) null, (null) null, (null) null, (null) null, (null) null, (null) null, (null) null, (long) 1111111, (null) null, (String) Y, (null) null]} [code=12899, state=72000] | ||
FailedObject: gov.va.vba.vonapp.entities.VnpPerson@7482ee7b | ||
at org.apache.openjpa.jdbc.sql.DBDictionary.narrow(DBDictionary.java:4207) | ||
at org.apache.openjpa.jdbc.sql.DBDictionary.newStoreException(DBDictionary.java:4171) | ||
at org.apache.openjpa.jdbc.sql.SQLExceptions.getStore(SQLExceptions.java:102) | ||
at org.apache.openjpa.jdbc.sql.SQLExceptions.getStore(SQLExceptions.java:72) | ||
at kodo.jdbc.kernel.BatchingPreparedStatementManager.flushInternal(BatchingPreparedStatementManager.java:214) | ||
at kodo.jdbc.kernel.BatchingPreparedStatementManager.flushInternal(BatchingPreparedStatementManager.java:149) | ||
at kodo.jdbc.kernel.BatchingPreparedStatementManager.flush(BatchingPreparedStatementManager.java:72) | ||
at kodo.jdbc.kernel.AutoOrderUpdateManager.flush(AutoOrderUpdateManager.java:84) | ||
at kodo.jdbc.kernel.ConstraintUpdateManager.flush(ConstraintUpdateManager.java:68) | ||
at org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:89) | ||
at org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:72) | ||
at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.flush(JDBCStoreManager.java:569) | ||
at org.apache.openjpa.kernel.DelegatingStoreManager.flush(DelegatingStoreManager.java:130) | ||
at org.apache.openjpa.datacache.DataCacheStoreManager.flush(DataCacheStoreManager.java:571) | ||
at org.apache.openjpa.kernel.DelegatingStoreManager.flush(DelegatingStoreManager.java:130) | ||
... 93 more | ||
Caused by: org.apache.openjpa.lib.jdbc.ReportingSQLException: ORA-12899: value too large for column "CORPPROD"."VNP_PERSON"."MIDDLE_NM" (actual: 52, maximum: 30) | ||
{prepstmnt 121207984 INSERT INTO VNP_PERSON (VNP_PTCPNT_ID, BIRTH_CITY_NM, BIRTH_CNTRY_NM, BIRTH_STATE_CD, BRTHDY_DT, CMPTNY_DECN_TYPE_CD, DEATH_CITY_CNTRY_NM, DEATH_CNTRY_NM, DEATH_DT, DEATH_STATE_CD, DEP_NBR, EMP_IND, ENTLMT_TYPE_CD, ETHNIC_TYPE_CD, EVER_MARIED_IND, FID_DECN_CATEGY_TYPE_CD, FILE_NBR, FIRST_NM, FIRST_NM_KEY, FRGN_SVC_NBR, GENDER_CD, JRN_DT, JRN_LCTN_ID, JRN_OBJ_ID, JRN_STATUS_TYPE_CD, JRN_USER_ID, LAST_NM, LAST_NM_KEY, LGY_ENTLMT_TYPE_CD, MARTL_STATUS_TYPE_CD, MIDDLE_NM, MIDDLE_NM_KEY, MLTY_PERSON_IND, MONTHS_PRESNT_EMPLYR_NBR, NET_WORTH_AMT, NO_SSN_REASON_TYPE_CD, OCPTN_TXT, PERSON_DEATH_CAUSE_TYPE_NM, PERSON_TYPE_NM, POTNTL_DNGRS_IND, RACE_TYPE_NM, SBSTNC_AMT, SEROUS_EMPLMT_HNDCAP_IND, SLTTN_TYPE_NM, SPINA_BIFIDA_IND, SPOUSE_NUM, SSN_NBR, SSN_VRFCTN_STATUS_TYPE_CD, SUFFIX_NM, SUFFIX_NM_KEY, TAX_ABTMNT_CD, TERMNL_DIGIT_NBR, TITLE_TXT, VET_IND, VET_TYPE_NM, VNP_PROC_ID, VNP_SCHOOL_CHILD_IND, VNP_SRUSLY_DSABLD_IND, YEARS_PRESNT_EMPLYR_NBR) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) [params=(long) 11111111, (String) Foo, (null) null, (String) HI, (Date) 2008-06-20, (null) null, (null) null, (null) null, (null) null, (null) null, (null) null, (null) null, (null) null, (null) null, (String) N, (null) null, (null) null, (String) Bar, (null) null, (null) null, (null) null, (Timestamp) 2023-05-16 00:00:00.0, (String) 281, (String) VAgovAPI, (String) U, (String) VAgovAPI, (String) Baz, (null) null, (null) null, (null) null, (String) Foo, (null) null, (null) null, (null) null, (null) null, (null) null, (null) null, (null) null, (null) null, (null) null, (null) null, (null) null, (null) null, (null) null, (null) null, (null) null, (String) 11111111, (null) null, (null) null, (null) null, (null) null, (null) null, (null) null, (null) null, (null) null, (long) 1111111, (null) null, (String) Y, (null) null]} [code=12899, state=72000] | ||
at org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator.wrap(LoggingConnectionDecorator.java:192) | ||
at org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator.access$700(LoggingConnectionDecorator.java:57) | ||
at org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator$LoggingConnection$LoggingPreparedStatement.executeUpdate(LoggingConnectionDecorator.java:866) | ||
at org.apache.openjpa.lib.jdbc.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:269) | ||
at org.apache.openjpa.jdbc.kernel.JDBCStoreManager$CancelPreparedStatement.executeUpdate(JDBCStoreManager.java:1453) | ||
at kodo.jdbc.kernel.BatchingPreparedStatementManager.flushInternal(BatchingPreparedStatementManager.java:208) | ||
... 103 more |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'rails_helper' | ||
require 'bgs/exceptions/bgs_errors' | ||
|
||
RSpec.describe BGS::Exceptions::BGSErrors do | ||
let(:dummy_class) do | ||
Class.new do | ||
include BGS::Exceptions::BGSErrors | ||
attr_reader :user | ||
|
||
def initialize | ||
@user = { icn: '1234' } | ||
end | ||
end | ||
end | ||
let(:dummy_instance) { dummy_class.new } | ||
|
||
describe '#notify_of_service_exception' do | ||
context 'large stacktrace with oracle error message and PII returned' do | ||
it 'logs the oracle error message to Sentry, but not the stacktrace or PII' do | ||
error_message = File.read('spec/fixtures/bgs/bgs_oracle_error.txt') | ||
dummy_error = StandardError.new(error_message) | ||
expect(dummy_instance).to receive(:log_message_to_sentry).with( | ||
'ORA-12899: value too large for column "CORPPROD"."VNP_PERSON"."MIDDLE_NM" (actual: 52, maximum: 30)', | ||
:error, | ||
{ icn: '1234' }, | ||
{ team: 'vfs-ebenefits' } | ||
) | ||
expect do | ||
dummy_instance.notify_of_service_exception(dummy_error, 'dummy_method') | ||
end.to raise_error(BGS::ServiceException) | ||
end | ||
end | ||
|
||
context 'error not related to oracle' do | ||
it "raises a BGS::ServiceException with BGS's raw error message" do | ||
dummy_error = StandardError.new('(ns0:Server) insertBenefitClaim: City is null') | ||
expect(dummy_instance).not_to receive(:log_message_to_sentry) | ||
expect do | ||
dummy_instance.notify_of_service_exception(dummy_error, 'dummy_method') | ||
end.to raise_error(BGS::ServiceException) | ||
end | ||
end | ||
|
||
context 'no error message' do | ||
it 'raises a BGS::ServiceException' do | ||
dummy_error = StandardError.new | ||
expect(dummy_instance).not_to receive(:log_message_to_sentry) | ||
expect do | ||
dummy_instance.notify_of_service_exception(dummy_error, 'dummy_method') | ||
end.to raise_error(BGS::ServiceException) | ||
end | ||
end | ||
end | ||
end |