From 205b27a2676efa51df1ee51a6731c7fe9942422a Mon Sep 17 00:00:00 2001 From: Kirill Solomko Date: Wed, 20 Mar 2024 18:29:59 +0100 Subject: [PATCH] MT#59478 API better transaction and error handling * Role/Entities*: POST/PUT/PATCH/DELETE methods changes: - support deadlock detection and transaction retry (2 retry attempts at the moment) - improve transaction control, use local $guard instead of saving the ref to $c->stash, as in that case it went out of scope too late and also reported an error message into the log about abnormal $guard out of scope interruption - move all non transaction related code outside of the scope - add error handling when methods such as update_item, and a like do not return the expected data, instead of simply going out of scope and resulting in an uncontrolled reply * Role/API: - rework transaction control: + get_transaction_control() is renamed to start_transaction() to better reflect what it does + complete_transaction() is renamed to commit_transaction() + remove unused %params arg + pass $guard into commit_transaction() instead of having it stored as $c->stash->{transaction_guard) that caused the $guard ref to be destroyed much late than expected (there was also a typo as transaction_quard, which is not relevant anymore with the changes + add check_deadlock() that is invoked when an exception is caught or an $c->errors contain an error, and if the error message represents a transaction error, the transaction block is re-invoked via "goto TX_START" - rework error(): + it now accepts args as following: ($self, $c, $code, $message, @errors) # code -> returned as HTTP code in the reply # message -> returned as HTTP message in the reply # errors -> contain errors for internal logging, last element often contains a DBIx exception + populates all @errors into $c->error so they are available on demend in the code via $c->error or $c->last_error + $c->log->error is not invoked now as the errors become printed in log_response() - log_response() now prints collected errors from $c->error correctly as a separate log line, that is alike to the other api logs so that those can be looked up by the request's tx_id, also all errors are now printed only into api.log * Adjust all $self->error() calls in catch($e) to include $e as the last argument, as well as the duplicate $c->log->error is removed from those ocassions * Remove all $c->log->error() calls as they are replaced with either $self->error() (that logs it correctly into api.log) or $c->error('err') that also adds it correctly into api.log * API::CallForwards: rework to use Entities/EntitiesItem * API::Contracts: rework POST to use Entities * API::PeeringGroups: rework POST to use Entities * API::SubscriberRegistrations: rework POST to use Entities * API::RewriteRuleSets: improve create_item() functionality * Utils/Message: add 'api_retry' log type * $c->session->{api_request_tx_id} is changed to $c->stash->{api_request_tx_id} because sometimes the session ref is different and a different tx_id becomes used Change-Id: I633ce7a8047b1bf00a2f6889003088edf0825dcd --- lib/NGCP/Panel/Controller/API/AdminCerts.pm | 2 +- .../Panel/Controller/API/AdminCertsItem.pm | 3 +- lib/NGCP/Panel/Controller/API/Admins.pm | 3 +- .../Panel/Controller/API/ApplyRewrites.pm | 11 +- lib/NGCP/Panel/Controller/API/BillingFees.pm | 7 +- .../Panel/Controller/API/BillingFeesItem.pm | 4 +- .../Panel/Controller/API/BillingNetworks.pm | 3 +- .../Controller/API/BillingNetworksItem.pm | 4 +- .../Panel/Controller/API/BillingProfiles.pm | 6 +- .../Controller/API/BillingProfilesItem.pm | 4 +- lib/NGCP/Panel/Controller/API/BillingZones.pm | 3 +- .../Panel/Controller/API/BillingZonesItem.pm | 4 +- .../Panel/Controller/API/CCMapEntriesItem.pm | 4 +- .../Panel/Controller/API/CFBNumberSets.pm | 3 +- .../Panel/Controller/API/CFDestinationSets.pm | 3 +- .../Controller/API/CFDestinationSetsItem.pm | 4 +- lib/NGCP/Panel/Controller/API/CFSourceSets.pm | 3 +- .../Panel/Controller/API/CFSourceSetsItem.pm | 4 +- lib/NGCP/Panel/Controller/API/CFTimeSets.pm | 3 +- .../Panel/Controller/API/CFTimeSetsItem.pm | 4 +- lib/NGCP/Panel/Controller/API/CallControls.pm | 7 +- lib/NGCP/Panel/Controller/API/CallForwards.pm | 44 --- .../Panel/Controller/API/CallForwardsItem.pm | 125 +------ .../Controller/API/CallRecordingFilesItem.pm | 3 +- .../API/CallRecordingStreamsItem.pm | 3 +- .../Controller/API/CallRecordingsItem.pm | 3 +- lib/NGCP/Panel/Controller/API/Contracts.pm | 171 ++++----- .../Panel/Controller/API/CustomerContacts.pm | 3 +- .../Controller/API/CustomerContactsItem.pm | 4 +- .../Panel/Controller/API/CustomerLocations.pm | 3 +- .../Controller/API/CustomerLocationsItem.pm | 4 +- lib/NGCP/Panel/Controller/API/Customers.pm | 9 +- lib/NGCP/Panel/Controller/API/Domains.pm | 6 +- lib/NGCP/Panel/Controller/API/DomainsItem.pm | 3 +- .../Panel/Controller/API/EmailTemplates.pm | 8 +- .../API/EmergencyMappingContainers.pm | 8 +- .../API/EmergencyMappingContainersItem.pm | 4 +- .../Panel/Controller/API/EmergencyMappings.pm | 18 +- lib/NGCP/Panel/Controller/API/Faxes.pm | 11 +- .../Controller/API/FaxserverSettingsItem.pm | 7 +- .../Panel/Controller/API/HeaderRuleActions.pm | 3 +- .../Controller/API/HeaderRuleConditions.pm | 3 +- .../Panel/Controller/API/HeaderRuleSets.pm | 3 +- lib/NGCP/Panel/Controller/API/HeaderRules.pm | 6 +- .../Panel/Controller/API/Interceptions.pm | 8 +- .../Panel/Controller/API/InterceptionsItem.pm | 1 - lib/NGCP/Panel/Controller/API/LnpCarriers.pm | 7 +- .../Panel/Controller/API/LnpCarriersItem.pm | 4 +- lib/NGCP/Panel/Controller/API/LnpNumbers.pm | 12 +- .../Controller/API/ManagerSecretaryItem.pm | 4 +- lib/NGCP/Panel/Controller/API/NcosLevels.pm | 8 +- .../Panel/Controller/API/NcosLnpCarriers.pm | 12 +- .../Panel/Controller/API/NcosLnpPatterns.pm | 7 +- lib/NGCP/Panel/Controller/API/NcosPatterns.pm | 11 +- lib/NGCP/Panel/Controller/API/NumbersItem.pm | 3 +- .../Panel/Controller/API/PartyCallControls.pm | 12 +- .../Panel/Controller/API/PasswordRecovery.pm | 25 +- .../Panel/Controller/API/PbxDeviceConfigs.pm | 7 +- .../Controller/API/PbxDeviceFirmwares.pm | 7 +- .../Panel/Controller/API/PbxDeviceProfiles.pm | 16 +- .../Controller/API/PbxDeviceProfilesItem.pm | 2 - lib/NGCP/Panel/Controller/API/PbxDevices.pm | 3 +- .../Panel/Controller/API/PbxDevicesItem.pm | 4 +- .../Panel/Controller/API/PeeringGroups.pm | 57 +-- .../Controller/API/PeeringInboundRules.pm | 6 +- lib/NGCP/Panel/Controller/API/PeeringRules.pm | 4 +- .../Panel/Controller/API/PeeringServers.pm | 11 +- .../Controller/API/PeeringServersItem.pm | 12 +- .../Panel/Controller/API/ProfilePackages.pm | 4 +- .../API/ProvisioningTemplatesItem.pm | 14 +- lib/NGCP/Panel/Controller/API/Reminders.pm | 11 +- lib/NGCP/Panel/Controller/API/Resellers.pm | 3 +- .../Panel/Controller/API/RewriteRuleSets.pm | 18 +- .../Controller/API/RewriteRuleSetsItem.pm | 8 +- lib/NGCP/Panel/Controller/API/RewriteRules.pm | 3 +- .../Panel/Controller/API/RewriteRulesItem.pm | 8 +- lib/NGCP/Panel/Controller/API/SMS.pm | 5 +- lib/NGCP/Panel/Controller/API/SoundSets.pm | 3 +- .../Panel/Controller/API/SoundSetsItem.pm | 4 +- .../API/SubscriberLocationMappings.pm | 7 +- .../Controller/API/SubscriberProfileSets.pm | 12 +- .../API/SubscriberProfileSetsItem.pm | 12 +- .../Controller/API/SubscriberProfiles.pm | 16 +- .../Controller/API/SubscriberProfilesItem.pm | 4 +- .../Controller/API/SubscriberRegistrations.pm | 38 +- lib/NGCP/Panel/Controller/API/Subscribers.pm | 12 +- .../Panel/Controller/API/SystemContacts.pm | 3 +- .../Controller/API/SystemContactsItem.pm | 4 +- lib/NGCP/Panel/Controller/API/TimeSets.pm | 3 +- lib/NGCP/Panel/Controller/API/TopupCash.pm | 14 +- .../Panel/Controller/API/TopupVouchers.pm | 14 +- .../Panel/Controller/API/TrustedSources.pm | 10 +- .../Controller/API/TrustedSourcesItem.pm | 9 +- .../Panel/Controller/API/UpnRewriteSets.pm | 7 +- lib/NGCP/Panel/Controller/API/Vouchers.pm | 11 +- lib/NGCP/Panel/Controller/API/VouchersItem.pm | 12 +- lib/NGCP/Panel/Role/API.pm | 85 +++-- lib/NGCP/Panel/Role/API/Admins.pm | 8 +- lib/NGCP/Panel/Role/API/AutoAttendants.pm | 3 +- lib/NGCP/Panel/Role/API/BillingNetworks.pm | 4 +- lib/NGCP/Panel/Role/API/BillingProfiles.pm | 4 +- lib/NGCP/Panel/Role/API/CCMapEntries.pm | 3 +- lib/NGCP/Panel/Role/API/CFBNumberSets.pm | 3 +- lib/NGCP/Panel/Role/API/CFDestinationSets.pm | 3 +- lib/NGCP/Panel/Role/API/CFSourceSets.pm | 7 +- lib/NGCP/Panel/Role/API/CFTimeSets.pm | 3 +- lib/NGCP/Panel/Role/API/CallForwards.pm | 18 +- lib/NGCP/Panel/Role/API/CallQueues.pm | 6 +- lib/NGCP/Panel/Role/API/Contracts.pm | 7 +- .../Panel/Role/API/CustomerFraudEvents.pm | 3 +- .../Role/API/CustomerFraudPreferences.pm | 2 +- lib/NGCP/Panel/Role/API/CustomerLocations.pm | 2 +- .../Role/API/CustomerPhonebookEntries.pm | 3 - lib/NGCP/Panel/Role/API/Customers.pm | 5 +- lib/NGCP/Panel/Role/API/EmailTemplates.pm | 4 +- .../Role/API/EmergencyMappingContainers.pm | 8 +- lib/NGCP/Panel/Role/API/EmergencyMappings.pm | 8 +- lib/NGCP/Panel/Role/API/FaxserverSettings.pm | 7 +- lib/NGCP/Panel/Role/API/Interceptions.pm | 10 +- lib/NGCP/Panel/Role/API/InvoiceTemplates.pm | 4 +- lib/NGCP/Panel/Role/API/LnpCarriers.pm | 4 +- lib/NGCP/Panel/Role/API/LnpNumbers.pm | 4 +- lib/NGCP/Panel/Role/API/MailToFaxSettings.pm | 5 +- lib/NGCP/Panel/Role/API/ManagerSecretary.pm | 3 +- lib/NGCP/Panel/Role/API/NcosLevels.pm | 5 +- lib/NGCP/Panel/Role/API/NcosLnpCarriers.pm | 8 +- lib/NGCP/Panel/Role/API/NcosLnpPatterns.pm | 8 +- lib/NGCP/Panel/Role/API/NcosPatterns.pm | 9 +- lib/NGCP/Panel/Role/API/PbxDeviceConfigs.pm | 4 +- lib/NGCP/Panel/Role/API/PbxDeviceFirmwares.pm | 4 +- lib/NGCP/Panel/Role/API/PbxDeviceModels.pm | 24 +- lib/NGCP/Panel/Role/API/PbxDeviceProfiles.pm | 8 +- lib/NGCP/Panel/Role/API/PbxDevices.pm | 13 +- lib/NGCP/Panel/Role/API/PeeringGroups.pm | 3 +- .../Panel/Role/API/PeeringInboundRules.pm | 3 - lib/NGCP/Panel/Role/API/PeeringRules.pm | 1 - lib/NGCP/Panel/Role/API/PeeringServers.pm | 4 +- lib/NGCP/Panel/Role/API/ProfilePackages.pm | 4 +- lib/NGCP/Panel/Role/API/Reminders.pm | 12 +- lib/NGCP/Panel/Role/API/ResellerBrandings.pm | 8 +- .../Role/API/ResellerPhonebookEntries.pm | 3 - lib/NGCP/Panel/Role/API/RewriteRuleSets.pm | 3 +- lib/NGCP/Panel/Role/API/SoundFiles.pm | 27 +- lib/NGCP/Panel/Role/API/SoundSets.pm | 28 +- lib/NGCP/Panel/Role/API/SpeedDials.pm | 3 +- .../Role/API/SubscriberLocationMappings.pm | 4 +- .../Role/API/SubscriberPhonebookEntries.pm | 3 - .../Panel/Role/API/SubscriberProfileSets.pm | 4 +- lib/NGCP/Panel/Role/API/SubscriberProfiles.pm | 9 +- lib/NGCP/Panel/Role/API/Subscribers.pm | 26 +- lib/NGCP/Panel/Role/API/TimeSets.pm | 7 +- lib/NGCP/Panel/Role/API/TrustedSources.pm | 4 +- lib/NGCP/Panel/Role/API/UpnRewriteSets.pm | 8 +- lib/NGCP/Panel/Role/API/VoicemailSettings.pm | 4 +- lib/NGCP/Panel/Role/API/Vouchers.pm | 4 +- lib/NGCP/Panel/Role/Entities.pm | 158 +++++--- lib/NGCP/Panel/Role/EntitiesItem.pm | 342 ++++++++++++------ lib/NGCP/Panel/Utils/DeviceBootstrap/ALE.pm | 2 +- lib/NGCP/Panel/Utils/DeviceBootstrap/Snom.pm | 2 +- lib/NGCP/Panel/Utils/Journal.pm | 2 +- lib/NGCP/Panel/Utils/Message.pm | 13 +- lib/NGCP/Panel/Utils/ProfilePackages.pm | 2 +- 162 files changed, 952 insertions(+), 1103 deletions(-) diff --git a/lib/NGCP/Panel/Controller/API/AdminCerts.pm b/lib/NGCP/Panel/Controller/API/AdminCerts.pm index 7d12c487e8..0ea061d817 100644 --- a/lib/NGCP/Panel/Controller/API/AdminCerts.pm +++ b/lib/NGCP/Panel/Controller/API/AdminCerts.pm @@ -65,7 +65,7 @@ sub create_item { my $err; my $res = NGCP::Panel::Utils::Auth::generate_client_cert($c, $admin, sub { my $e = shift; - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to generate client certificate"); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to generate client certificate", $e); $err = 1; }); return if $err; diff --git a/lib/NGCP/Panel/Controller/API/AdminCertsItem.pm b/lib/NGCP/Panel/Controller/API/AdminCertsItem.pm index e9b34c582e..3564aa0864 100644 --- a/lib/NGCP/Panel/Controller/API/AdminCertsItem.pm +++ b/lib/NGCP/Panel/Controller/API/AdminCertsItem.pm @@ -33,8 +33,7 @@ sub delete_item { ssl_client_certificate => undef, }); } catch($e) { - $c->log->error("failed to delete administrator certificate: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to delete administrator certificate."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to delete administrator certificate.", $e); return; } diff --git a/lib/NGCP/Panel/Controller/API/Admins.pm b/lib/NGCP/Panel/Controller/API/Admins.pm index 5dab687a11..2b3b0a49b9 100644 --- a/lib/NGCP/Panel/Controller/API/Admins.pm +++ b/lib/NGCP/Panel/Controller/API/Admins.pm @@ -59,8 +59,7 @@ sub create_item { try { $item = $c->model('DB')->resultset('admins')->create($resource); } catch($e) { - $c->log->error("failed to create admin: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create admin."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create admin.", $e); return; } diff --git a/lib/NGCP/Panel/Controller/API/ApplyRewrites.pm b/lib/NGCP/Panel/Controller/API/ApplyRewrites.pm index d66210d72f..0a5b3d2e15 100644 --- a/lib/NGCP/Panel/Controller/API/ApplyRewrites.pm +++ b/lib/NGCP/Panel/Controller/API/ApplyRewrites.pm @@ -72,13 +72,13 @@ sub POST :Allow { } my $subscriber = $subscriber_rs->first; unless($subscriber) { - $c->log->error("invalid subscriber id $$resource{subscriber_id} for outbound call"); - $self->error($c, HTTP_NOT_FOUND, "Calling subscriber not found."); + $self->error($c, HTTP_NOT_FOUND, "Calling subscriber not found.", + "invalid subscriber id $$resource{subscriber_id} for outbound call"); last; } if (($c->user->roles eq "subscriber" || $c->user->roles eq "subscriberadmin") && $subscriber->provisioning_voip_subscriber->id != $c->user->id) { - $c->log->error("Insuficient permissions to apply rewrites for subscriber id $$resource{subscriber_id}"); - $self->error($c, HTTP_FORBIDDEN, "Insuficient permissions."); + $self->error($c, HTTP_FORBIDDEN, "Insuficient permissions.", + "Insuficient permissions to apply rewrites for subscriber id $$resource{subscriber_id}"); return; } @@ -101,8 +101,7 @@ sub POST :Allow { push @result, $normalized; } } catch($e) { - $c->log->error("failed to rewrite number: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to rewrite number."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to rewrite number.", $e); last; } diff --git a/lib/NGCP/Panel/Controller/API/BillingFees.pm b/lib/NGCP/Panel/Controller/API/BillingFees.pm index 603ecbf6b2..1657fd3e31 100644 --- a/lib/NGCP/Panel/Controller/API/BillingFees.pm +++ b/lib/NGCP/Panel/Controller/API/BillingFees.pm @@ -176,8 +176,8 @@ sub POST :Allow { $c->response->body(q()); } catch($e) { - $c->log->error("failed to upload csv: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error"); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error", + "failed to upload csv", $e); last; }; } else { @@ -207,8 +207,7 @@ sub POST :Allow { return_created => 1, )->[0]; } catch($e) { - $c->log->error("failed to create billing fee: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create billing fee."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create billing fee.", $e); last; } $guard->commit; diff --git a/lib/NGCP/Panel/Controller/API/BillingFeesItem.pm b/lib/NGCP/Panel/Controller/API/BillingFeesItem.pm index 2dc7ef6364..4c4b2dd257 100644 --- a/lib/NGCP/Panel/Controller/API/BillingFeesItem.pm +++ b/lib/NGCP/Panel/Controller/API/BillingFeesItem.pm @@ -125,8 +125,8 @@ sub DELETE :Allow { try { $fee->delete; } catch($e) { - $c->log->error("Failed to delete billing fee with id '$id': $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error"); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error", + "Failed to delete billing fee with id '$id'", $e); last; } diff --git a/lib/NGCP/Panel/Controller/API/BillingNetworks.pm b/lib/NGCP/Panel/Controller/API/BillingNetworks.pm index 27638da6ca..d59d73c057 100644 --- a/lib/NGCP/Panel/Controller/API/BillingNetworks.pm +++ b/lib/NGCP/Panel/Controller/API/BillingNetworks.pm @@ -157,8 +157,7 @@ sub POST :Allow { $bn->create_related("billing_network_blocks", $block); } } catch($e) { - $c->log->error("failed to create billingnetwork: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create billingnetwork."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create billingnetwork.", $e); return; }; diff --git a/lib/NGCP/Panel/Controller/API/BillingNetworksItem.pm b/lib/NGCP/Panel/Controller/API/BillingNetworksItem.pm index 9ae79d244f..88da24ab19 100644 --- a/lib/NGCP/Panel/Controller/API/BillingNetworksItem.pm +++ b/lib/NGCP/Panel/Controller/API/BillingNetworksItem.pm @@ -153,8 +153,8 @@ sub DELETE :Allow { status => 'terminated' }); } catch($e) { - $c->log->error("Failed to terminate billingnetwork with id '$id': $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error"); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error", + "Failed to terminate billingnetwork with id '$id'", $e); last; } $guard->commit; diff --git a/lib/NGCP/Panel/Controller/API/BillingProfiles.pm b/lib/NGCP/Panel/Controller/API/BillingProfiles.pm index c29650c89f..598f60b015 100644 --- a/lib/NGCP/Panel/Controller/API/BillingProfiles.pm +++ b/lib/NGCP/Panel/Controller/API/BillingProfiles.pm @@ -182,12 +182,10 @@ sub POST :Allow { $log_error = "failed to create subscriber, reseller-billing profile combination " . $c->qs($1) . " already exists"; @http_errors = ("Reseller-Billing Profile name combination '" . $1 . "' already exists.", "Reseller-Billing Profile name combination already exists."); } - $c->log->error($log_error); # TODO: user, message, trace, ... - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, $http_errors[0], $http_errors[1]); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, $http_errors[0], $http_errors[1], $log_error); last; } catch($e) { - $c->log->error("failed to create billing profile: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create billing profile."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create billing profile.", $e); last; } diff --git a/lib/NGCP/Panel/Controller/API/BillingProfilesItem.pm b/lib/NGCP/Panel/Controller/API/BillingProfilesItem.pm index dc0db8665b..a51704de21 100644 --- a/lib/NGCP/Panel/Controller/API/BillingProfilesItem.pm +++ b/lib/NGCP/Panel/Controller/API/BillingProfilesItem.pm @@ -173,8 +173,8 @@ sub DELETE :Allow { terminate_timestamp => NGCP::Panel::Utils::DateTime::current_local }); } catch($e) { - $c->log->error("Failed to terminate billingprofile with id '$id': $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error"); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error", + "Failed to terminate billingprofile with id '$id'", $e); last; } $guard->commit; diff --git a/lib/NGCP/Panel/Controller/API/BillingZones.pm b/lib/NGCP/Panel/Controller/API/BillingZones.pm index 651a7904c6..0af8e66ed7 100644 --- a/lib/NGCP/Panel/Controller/API/BillingZones.pm +++ b/lib/NGCP/Panel/Controller/API/BillingZones.pm @@ -140,8 +140,7 @@ sub POST :Allow { try { $zone = $profile->billing_zones->create($resource); } catch($e) { - $c->log->error("failed to create billing zone: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create billing zone."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create billing zone.", $e); last; } diff --git a/lib/NGCP/Panel/Controller/API/BillingZonesItem.pm b/lib/NGCP/Panel/Controller/API/BillingZonesItem.pm index ac7acf9aa8..9688d01203 100644 --- a/lib/NGCP/Panel/Controller/API/BillingZonesItem.pm +++ b/lib/NGCP/Panel/Controller/API/BillingZonesItem.pm @@ -146,8 +146,8 @@ sub DELETE :Allow { $zone->billing_fees->delete_all; $zone->delete; } catch($e) { - $c->log->error("Failed to delete billing zone with id '$id': $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error"); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error", + "Failed to delete billing zone with id '$id'", $e); last; } $guard->commit; diff --git a/lib/NGCP/Panel/Controller/API/CCMapEntriesItem.pm b/lib/NGCP/Panel/Controller/API/CCMapEntriesItem.pm index 5ea04fe67b..293c7939ac 100644 --- a/lib/NGCP/Panel/Controller/API/CCMapEntriesItem.pm +++ b/lib/NGCP/Panel/Controller/API/CCMapEntriesItem.pm @@ -150,8 +150,8 @@ sub DELETE :Allow { try { $prov_subs->voip_cc_mappings->delete; } catch($e) { - $c->log->error("Failed to delete ccmapentries with id '$id': $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error"); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error", + "Failed to delete ccmapentries with id '$id'", $e); last; } $guard->commit; diff --git a/lib/NGCP/Panel/Controller/API/CFBNumberSets.pm b/lib/NGCP/Panel/Controller/API/CFBNumberSets.pm index a818e448c8..ba8febe64f 100644 --- a/lib/NGCP/Panel/Controller/API/CFBNumberSets.pm +++ b/lib/NGCP/Panel/Controller/API/CFBNumberSets.pm @@ -84,8 +84,7 @@ sub create_item { return $self->hal_from_item($c, $_bset); }); } } catch($e) { - $c->log->error("failed to create cfbnumberset: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create cfbnumberset."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create cfbnumberset.", $e); return; } diff --git a/lib/NGCP/Panel/Controller/API/CFDestinationSets.pm b/lib/NGCP/Panel/Controller/API/CFDestinationSets.pm index fd1e560767..ae7fd324f1 100644 --- a/lib/NGCP/Panel/Controller/API/CFDestinationSets.pm +++ b/lib/NGCP/Panel/Controller/API/CFDestinationSets.pm @@ -190,8 +190,7 @@ sub POST :Allow { $dset->create_related("voip_cf_destinations", $d); } } catch($e) { - $c->log->error("failed to create cfdestinationset: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create cfdestinationset."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create cfdestinationset.", $e); last; } diff --git a/lib/NGCP/Panel/Controller/API/CFDestinationSetsItem.pm b/lib/NGCP/Panel/Controller/API/CFDestinationSetsItem.pm index 4d5e9fdd71..5b057f18d5 100644 --- a/lib/NGCP/Panel/Controller/API/CFDestinationSetsItem.pm +++ b/lib/NGCP/Panel/Controller/API/CFDestinationSetsItem.pm @@ -149,8 +149,8 @@ sub DELETE :Allow { try { $dset->delete; } catch($e) { - $c->log->error("Failed to delete cfdestinationset with id '$id': $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error"); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error", + "Failed to delete cfdestinationset with id '$id'", $e); last; } $guard->commit; diff --git a/lib/NGCP/Panel/Controller/API/CFSourceSets.pm b/lib/NGCP/Panel/Controller/API/CFSourceSets.pm index eb527e5a15..081cb9cecd 100644 --- a/lib/NGCP/Panel/Controller/API/CFSourceSets.pm +++ b/lib/NGCP/Panel/Controller/API/CFSourceSets.pm @@ -138,8 +138,7 @@ sub create_item { return $self->hal_from_item($c, $_sset, "cfsourcesets"); }); } catch($e) { - $c->log->error("failed to create source_set: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create source_set."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create source_set.", $e); return; } diff --git a/lib/NGCP/Panel/Controller/API/CFSourceSetsItem.pm b/lib/NGCP/Panel/Controller/API/CFSourceSetsItem.pm index 7c01c6fec3..bea2c32fb5 100644 --- a/lib/NGCP/Panel/Controller/API/CFSourceSetsItem.pm +++ b/lib/NGCP/Panel/Controller/API/CFSourceSetsItem.pm @@ -149,8 +149,8 @@ sub DELETE :Allow { try { $sset->delete; } catch($e) { - $c->log->error("Failed to delete cfsourceset with id '$id': $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error"); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error", + "Failed to delete cfsourceset with id '$id'", $e); last; } $guard->commit; diff --git a/lib/NGCP/Panel/Controller/API/CFTimeSets.pm b/lib/NGCP/Panel/Controller/API/CFTimeSets.pm index a10001c33f..cfcc121ef5 100644 --- a/lib/NGCP/Panel/Controller/API/CFTimeSets.pm +++ b/lib/NGCP/Panel/Controller/API/CFTimeSets.pm @@ -162,8 +162,7 @@ sub POST :Allow { $tset->create_related("voip_cf_periods", $t); } } catch($e) { - $c->log->error("failed to create cftimeset: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create cftimeset."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create cftimeset.", $e); last; } diff --git a/lib/NGCP/Panel/Controller/API/CFTimeSetsItem.pm b/lib/NGCP/Panel/Controller/API/CFTimeSetsItem.pm index 665de8d1ad..22983bda36 100644 --- a/lib/NGCP/Panel/Controller/API/CFTimeSetsItem.pm +++ b/lib/NGCP/Panel/Controller/API/CFTimeSetsItem.pm @@ -149,8 +149,8 @@ sub DELETE :Allow { try { $tset->delete; } catch($e) { - $c->log->error("Failed to delete cftimeset with id '$id': $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error"); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error", + "Failed to delete cftimeset with id '$id'", $e); last; } $guard->commit; diff --git a/lib/NGCP/Panel/Controller/API/CallControls.pm b/lib/NGCP/Panel/Controller/API/CallControls.pm index 7ced2a9ac4..fc448bbe05 100644 --- a/lib/NGCP/Panel/Controller/API/CallControls.pm +++ b/lib/NGCP/Panel/Controller/API/CallControls.pm @@ -75,8 +75,8 @@ sub POST :Allow { } my $subscriber = $subscriber_rs->first; unless($subscriber) { - $c->log->error("invalid subscriber id $$resource{subscriber_id} for outbound call"); - $self->error($c, HTTP_NOT_FOUND, "Calling subscriber not found."); + $self->error($c, HTTP_NOT_FOUND, "Calling subscriber not found.", + "invalid subscriber id $$resource{subscriber_id} for outbound call"); last; } @@ -87,8 +87,7 @@ sub POST :Allow { NGCP::Panel::Utils::Sems::dial_out($c, $subscriber->provisioning_voip_subscriber, $callee_user, $callee_domain); } catch($e) { - $c->log->error("failed to dial out: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create call."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create call.", $e); last; } diff --git a/lib/NGCP/Panel/Controller/API/CallForwards.pm b/lib/NGCP/Panel/Controller/API/CallForwards.pm index d6f085048b..afb597dd98 100644 --- a/lib/NGCP/Panel/Controller/API/CallForwards.pm +++ b/lib/NGCP/Panel/Controller/API/CallForwards.pm @@ -62,50 +62,6 @@ __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller ccareadmin ccare subscriberadmin subscriber/], }); -sub GET :Allow { - my ($self, $c) = @_; - my $page = $c->request->params->{page} // 1; - my $rows = $c->request->params->{rows} // 10; - { - my $cfs = $self->item_rs($c, "callforwards"); - (my $total_count, $cfs, my $cfs_rows) = $self->paginate_order_collection($c, $cfs); - my (@embedded, @links); - my $form = $self->get_form($c); - for my $cf (@$cfs_rows) { - try { - push @embedded, $self->hal_from_item($c, $cf, $form); - push @links, Data::HAL::Link->new( - relation => 'ngcp:'.$self->resource_name, - href => sprintf('%s%s', $self->dispatch_path, $cf->id), - ); - } - } - push @links, - Data::HAL::Link->new( - relation => 'curies', - href => 'http://purl.org/sipwise/ngcp-api/#rel-{rel}', - name => 'ngcp', - templated => true, - ), - Data::HAL::Link->new(relation => 'profile', href => 'http://purl.org/sipwise/ngcp-api/'), - $self->collection_nav_links($c, $page, $rows, $total_count, $c->request->path, $c->request->query_params); - - my $hal = Data::HAL->new( - embedded => [@embedded], - links => [@links], - ); - $hal->resource({ - total_count => $total_count, - }); - my $response = HTTP::Response->new(HTTP_OK, undef, - HTTP::Headers->new($hal->http_headers(skip_links => 1)), $hal->as_json); - $c->response->headers($response->headers); - $c->response->body($response->content); - return; - } - return; -} - 1; # vim: set tabstop=4 expandtab: diff --git a/lib/NGCP/Panel/Controller/API/CallForwardsItem.pm b/lib/NGCP/Panel/Controller/API/CallForwardsItem.pm index 37536e2cb1..852584a00d 100644 --- a/lib/NGCP/Panel/Controller/API/CallForwardsItem.pm +++ b/lib/NGCP/Panel/Controller/API/CallForwardsItem.pm @@ -44,128 +44,23 @@ __PACKAGE__->set_config({ } }); -sub GET :Allow { - my ($self, $c, $id) = @_; - { - last unless $self->valid_id($c, $id); - my $item = $self->item_by_id($c, $id); - last unless $self->resource_exists($c, 'callforward' => $item); - - my $hal = $self->hal_from_item($c, $item); - - my $response = HTTP::Response->new(HTTP_OK, undef, HTTP::Headers->new( - (map { # XXX Data::HAL must be able to generate links with multiple relations - s|rel="(http://purl.org/sipwise/ngcp-api/#rel-resellers)"|rel="item $1"|r - =~ s/rel=self/rel="item self"/r; - } $hal->http_headers), - ), $hal->as_json); - $c->response->headers($response->headers); - $c->response->body($response->content); - return; - } - return; -} +sub delete_item { + my ($self, $c, $item) = @_; -sub PATCH :Allow { - my ($self, $c, $id) = @_; - my $guard = $c->model('DB')->txn_scope_guard; - { - my $preference = $self->require_preference($c); - last unless $preference; - - my $json = $self->get_valid_patch_data( - c => $c, - id => $id, - media_type => 'application/json-patch+json', - ops => [qw/add replace remove copy/], - ); - last unless $json; - - my $item = $self->item_by_id($c, $id); - last unless $self->resource_exists($c, subs_for_callforwards => $item); - my $old_resource = $self->hal_from_item($c, $item)->resource; - my $resource = $self->apply_patch($c, $old_resource, $json); - last unless $resource; + my $id = $item->id; + try { my $form = $self->get_form($c); - $item = $self->update_item($c, $item, $old_resource, $resource, $form); - last unless $item; - - my $hal = $self->hal_from_item($c, $item); - last unless $self->add_update_journal_item_hal($c,{ hal => $hal, id => $id }); - - $guard->commit; - - $self->return_representation($c, 'hal' => $hal, 'preference' => $preference ); - } - return; -} - -sub PUT :Allow { - my ($self, $c, $id) = @_; - my $guard = $c->model('DB')->txn_scope_guard; - { - my $preference = $self->require_preference($c); - last unless $preference; - - my $item = $self->item_by_id($c, $id); - last unless $self->resource_exists($c, subs_for_callforward => $item); - my $resource = $self->get_valid_put_data( - c => $c, - id => $id, - media_type => 'application/json', - ); - last unless $resource; my $old_resource = undef; - - my $form = $self->get_form($c); + my $resource = {}; $item = $self->update_item($c, $item, $old_resource, $resource, $form); - last unless $item; - - my $hal = $self->hal_from_item($c, $item); - last unless $self->add_update_journal_item_hal($c,{ hal => $hal, id => $id }); - - $guard->commit; - - $self->return_representation($c, 'hal' => $hal, 'preference' => $preference ); + return $item; + } catch($e) { + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error", + "Failed to delete callforward with id '$id'", $e); + last; } - return; -} -sub DELETE :Allow { - my ($self, $c, $id) = @_; - my $guard = $c->model('DB')->txn_scope_guard; - { - my $item = $self->item_by_id($c, $id); - last unless $self->resource_exists($c, subs_for_callforward => $item); - my $form = $self->get_form($c); - my $old_resource = undef; - my $resource = $self->get_valid_put_data( - c => $c, - id => $id, - media_type => 'application/json', - ); - $resource //= {}; - - last unless $self->add_delete_journal_item_hal($c,{ hal_from_item => sub { - my $self = shift; - my ($c) = @_; - return $self->hal_from_item($c,$item); }, - id => $id}); - - try { - $item = $self->update_item($c, $item, $old_resource, $resource, $form); - } catch($e) { - $c->log->error("Failed to delete callforward with id '$id': $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error"); - last; - } - - $guard->commit; - - $c->response->status(HTTP_NO_CONTENT); - $c->response->body(q()); - } return; } diff --git a/lib/NGCP/Panel/Controller/API/CallRecordingFilesItem.pm b/lib/NGCP/Panel/Controller/API/CallRecordingFilesItem.pm index d80703cdf4..7fcc845a33 100644 --- a/lib/NGCP/Panel/Controller/API/CallRecordingFilesItem.pm +++ b/lib/NGCP/Panel/Controller/API/CallRecordingFilesItem.pm @@ -44,8 +44,7 @@ sub GET :Allow { try { $data = read_file($item->full_filename); } catch($e) { - $c->log->error("Failed to read stream file: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to read stream file."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to read stream file.", $e); last; } my $mime_type; diff --git a/lib/NGCP/Panel/Controller/API/CallRecordingStreamsItem.pm b/lib/NGCP/Panel/Controller/API/CallRecordingStreamsItem.pm index 4964f718a9..999483218b 100644 --- a/lib/NGCP/Panel/Controller/API/CallRecordingStreamsItem.pm +++ b/lib/NGCP/Panel/Controller/API/CallRecordingStreamsItem.pm @@ -65,8 +65,7 @@ sub DELETE :Allow { unlink($item->full_filename); $item->delete; } catch($e) { - $c->log->error("Failed to delete stream: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to delete stream."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to delete stream.", $e); last; } $guard->commit; diff --git a/lib/NGCP/Panel/Controller/API/CallRecordingsItem.pm b/lib/NGCP/Panel/Controller/API/CallRecordingsItem.pm index 450a7663a7..0bd44675d4 100644 --- a/lib/NGCP/Panel/Controller/API/CallRecordingsItem.pm +++ b/lib/NGCP/Panel/Controller/API/CallRecordingsItem.pm @@ -26,8 +26,7 @@ sub delete_item { force_delete => $c->request->params->{force_delete}, ); } catch($e) { - $c->log->error("failed to delete callrecording: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to delete callrecording."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to delete callrecording.", $e); return; } return 1; diff --git a/lib/NGCP/Panel/Controller/API/Contracts.pm b/lib/NGCP/Panel/Controller/API/Contracts.pm index 8dfa7ce1db..f918614c15 100644 --- a/lib/NGCP/Panel/Controller/API/Contracts.pm +++ b/lib/NGCP/Panel/Controller/API/Contracts.pm @@ -134,119 +134,88 @@ sub GET :Allow { return; } -sub POST :Allow { - my ($self, $c) = @_; +sub create_item { + my ($self, $c, $resource, $form, $process_extras) = @_; + my $schema = $c->model('DB'); - $c->model('DB')->set_transaction_isolation('READ COMMITTED'); - my $guard = $c->model('DB')->txn_scope_guard; - { - my $schema = $c->model('DB'); - my $resource = $self->get_valid_post_data( - c => $c, - media_type => 'application/json', - ); - last unless $resource; + my $syscontact = $schema->resultset('contacts') + ->search({ + 'me.status' => { '!=' => 'terminated' }, + })->find($resource->{contact_id}); - my $form = $self->get_form($c); - $resource->{contact_id} //= undef; - last unless $self->validate_form( - c => $c, - resource => $resource, - form => $form, - ); + unless($syscontact) { + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid 'contact_id'"); + return; + } - my $syscontact = $schema->resultset('contacts') - ->search({ - 'me.status' => { '!=' => 'terminated' }, - })->find($resource->{contact_id}); - unless($syscontact) { - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid 'contact_id'"); - last; - } + my $mappings_to_create = []; + last unless NGCP::Panel::Utils::BillingMappings::prepare_billing_mappings( + c => $c, + resource => $resource, + old_resource => undef, + mappings_to_create => $mappings_to_create, + err_code => sub { + my ($err) = @_; + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, $err); + }); - my $mappings_to_create = []; - last unless NGCP::Panel::Utils::BillingMappings::prepare_billing_mappings( + my $product_class = delete $resource->{type}; + my $product = $schema->resultset('products')->search_rs({ class => $product_class })->first; + unless($product) { + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid 'type'."); + return; + } + $resource->{product_id} = $product->id; + if ( + NGCP::Panel::Utils::Contract::is_peering_reseller_product( c => $c, product => $product ) + && + ( my $prepaid_billing_profile_exist = NGCP::Panel::Utils::BillingMappings::check_prepaid_profiles_exist( c => $c, - resource => $resource, - old_resource => undef, - mappings_to_create => $mappings_to_create, - err_code => sub { - my ($err) = @_; - #$c->log->error($err); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, $err); - }); - - my $product_class = delete $resource->{type}; - my $product = $schema->resultset('products')->search_rs({ class => $product_class })->first; - unless($product) { - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid 'type'."); - last; - } - $resource->{product_id} = $product->id; - if ( - NGCP::Panel::Utils::Contract::is_peering_reseller_product( c => $c, product => $product ) - && - ( my $prepaid_billing_profile_exist = NGCP::Panel::Utils::BillingMappings::check_prepaid_profiles_exist( - c => $c, - mappings_to_create => $mappings_to_create) ) - ) { - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Peering/reseller contract can't be connected to the prepaid billing profile $prepaid_billing_profile_exist."); - return; - } - - if (NGCP::Panel::Utils::Contract::is_peering_product( - c => $c, product => $product) && defined $resource->{max_subscribers}) { - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Peering contract should not have 'max_subscribers' defined."); - return; - } - - my $now = NGCP::Panel::Utils::DateTime::current_local; - $resource->{create_timestamp} = $now; - $resource->{modify_timestamp} = $now; - my $contract; - - try { - $contract = $schema->resultset('contracts')->create($resource); - } catch($e) { - $c->log->error("failed to create contract: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create contract."); - last; - } + mappings_to_create => $mappings_to_create) ) + ) { + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Peering/reseller contract can't be connected to the prepaid billing profile $prepaid_billing_profile_exist."); + return; + } - if($contract->contact->reseller_id) { - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "The contact_id is not a valid ngcp:systemcontacts item, but an ngcp:customercontacts item"); - last; - } + if (NGCP::Panel::Utils::Contract::is_peering_product( + c => $c, product => $product) && defined $resource->{max_subscribers}) { + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Peering contract should not have 'max_subscribers' defined."); + return; + } - try { - NGCP::Panel::Utils::BillingMappings::append_billing_mappings(c => $c, - contract => $contract, - mappings_to_create => $mappings_to_create, - ); + my $now = NGCP::Panel::Utils::DateTime::current_local; + $resource->{create_timestamp} = $now; + $resource->{modify_timestamp} = $now; + my $contract; - $contract = $self->contract_by_id($c, $contract->id,1,$now); - NGCP::Panel::Utils::ProfilePackages::create_initial_contract_balances(c => $c, - contract => $contract, - ); - } catch($e) { - $c->log->error("failed to create contract: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create contract."); - last; - } + try { + $contract = $schema->resultset('contracts')->create($resource); + } catch($e) { + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create contract.", $e); + return; + } - last unless $self->add_create_journal_item_hal($c,sub { - my $self = shift; - my ($c) = @_; - my $_contract = $self->contract_by_id($c, $contract->id, 1); - return $self->hal_from_contract($c,$_contract,$form,$now); }); + if($contract->contact->reseller_id) { + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "The contact_id is not a valid ngcp:systemcontacts item, but an ngcp:customercontacts item"); + return; + } - $guard->commit; + try { + NGCP::Panel::Utils::BillingMappings::append_billing_mappings(c => $c, + contract => $contract, + mappings_to_create => $mappings_to_create, + ); - $c->response->status(HTTP_CREATED); - $c->response->header(Location => sprintf('/%s%d', $c->request->path, $contract->id)); - $c->response->body(q()); + $contract = $self->contract_by_id($c, $contract->id,1,$now); + NGCP::Panel::Utils::ProfilePackages::create_initial_contract_balances(c => $c, + contract => $contract, + ); + } catch($e) { + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create contract.", $e); + return; } - return; + + return $contract; } 1; diff --git a/lib/NGCP/Panel/Controller/API/CustomerContacts.pm b/lib/NGCP/Panel/Controller/API/CustomerContacts.pm index 4593863700..75d0216c01 100644 --- a/lib/NGCP/Panel/Controller/API/CustomerContacts.pm +++ b/lib/NGCP/Panel/Controller/API/CustomerContacts.pm @@ -150,8 +150,7 @@ sub POST :Allow { try { $contact = $c->model('DB')->resultset('contacts')->create($resource); } catch($e) { - $c->log->error("failed to create contact: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create contact."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create contact.", $e); last; } diff --git a/lib/NGCP/Panel/Controller/API/CustomerContactsItem.pm b/lib/NGCP/Panel/Controller/API/CustomerContactsItem.pm index abd6450448..42733ed618 100644 --- a/lib/NGCP/Panel/Controller/API/CustomerContactsItem.pm +++ b/lib/NGCP/Panel/Controller/API/CustomerContactsItem.pm @@ -189,8 +189,8 @@ sub DELETE :Allow { }); $contact->discard_changes(); } catch($e) { - $c->log->error("Failed to terminate contact id '".$contact->id."': $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error.", + "Failed to terminate contact id '".$contact->id."'", $e); last; }; my $form = $self->get_form($c); diff --git a/lib/NGCP/Panel/Controller/API/CustomerLocations.pm b/lib/NGCP/Panel/Controller/API/CustomerLocations.pm index 7df8780e89..18202c8294 100644 --- a/lib/NGCP/Panel/Controller/API/CustomerLocations.pm +++ b/lib/NGCP/Panel/Controller/API/CustomerLocations.pm @@ -131,8 +131,7 @@ sub POST :Allow { $cl->create_related('voip_contract_location_blocks', $block); } } catch($e) { - $c->log->error("failed to create customer location: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create customer location."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create customer location.", $e); return; }; diff --git a/lib/NGCP/Panel/Controller/API/CustomerLocationsItem.pm b/lib/NGCP/Panel/Controller/API/CustomerLocationsItem.pm index 45ddcca3e0..6ec827ac09 100644 --- a/lib/NGCP/Panel/Controller/API/CustomerLocationsItem.pm +++ b/lib/NGCP/Panel/Controller/API/CustomerLocationsItem.pm @@ -142,8 +142,8 @@ sub DELETE :Allow { try { $cl->delete; } catch($e) { - $c->log->error("Failed to delete customre location with id '$id': $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error"); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error", + "Failed to delete customre location with id '$id'", $e); last; } $guard->commit; diff --git a/lib/NGCP/Panel/Controller/API/Customers.pm b/lib/NGCP/Panel/Controller/API/Customers.pm index 8d31016eaf..84e7fd8547 100644 --- a/lib/NGCP/Panel/Controller/API/Customers.pm +++ b/lib/NGCP/Panel/Controller/API/Customers.pm @@ -245,7 +245,6 @@ sub POST :Allow { mappings_to_create => $mappings_to_create, err_code => sub { my ($err) = @_; - #$c->log->error($err); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, $err); }); @@ -266,8 +265,8 @@ sub POST :Allow { $customer = $schema->resultset('contracts')->create($resource); $c->log->debug("customer id " . $customer->id . " created"); } catch($e) { - $c->log->error("failed to create customer contract: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create customer."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create customer.", + "failed to create customer contract", $e); last; } @@ -301,8 +300,8 @@ sub POST :Allow { contract => $customer, ); } catch($e) { - $c->log->error("failed to create customer contract: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create customer."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create customer.", + "failed to create customer contract", $e); last; } diff --git a/lib/NGCP/Panel/Controller/API/Domains.pm b/lib/NGCP/Panel/Controller/API/Domains.pm index 0a36fb1144..33f3e2d173 100644 --- a/lib/NGCP/Panel/Controller/API/Domains.pm +++ b/lib/NGCP/Panel/Controller/API/Domains.pm @@ -160,8 +160,7 @@ sub POST :Allow { domain => $resource->{domain} }); } catch($e) { - $c->log->error("failed to create domain: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create domain."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create domain.", $e); last; } @@ -177,8 +176,7 @@ sub POST :Allow { $self->xmpp_domain_reload($c, $resource->{domain}) if $xmpp_reload; NGCP::Panel::Utils::XMLDispatcher::sip_domain_reload($c, $resource->{domain}) if ($sip_reload); } catch($e) { - $c->log->error("failed to activate domain: $e. Domain created"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to activate domain. Domain was created"); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to activate domain. Domain was created", $e); $c->response->header(Location => sprintf('/%s%d', $c->request->path, $billing_domain->id)); last; } diff --git a/lib/NGCP/Panel/Controller/API/DomainsItem.pm b/lib/NGCP/Panel/Controller/API/DomainsItem.pm index ff085a8456..d847667109 100644 --- a/lib/NGCP/Panel/Controller/API/DomainsItem.pm +++ b/lib/NGCP/Panel/Controller/API/DomainsItem.pm @@ -105,8 +105,7 @@ sub DELETE :Allow { $self->xmpp_domain_disable($c, $domain->domain) if $xmpp_reload; NGCP::Panel::Utils::XMLDispatcher::sip_domain_reload($c) if $sip_reload; } catch($e) { - $c->log->error("failed to deactivate domain: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to deactivate domain."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to deactivate domain.", $e); last; } diff --git a/lib/NGCP/Panel/Controller/API/EmailTemplates.pm b/lib/NGCP/Panel/Controller/API/EmailTemplates.pm index 8c5391ac26..19054f5cc2 100644 --- a/lib/NGCP/Panel/Controller/API/EmailTemplates.pm +++ b/lib/NGCP/Panel/Controller/API/EmailTemplates.pm @@ -131,16 +131,16 @@ sub POST :Allow { name => $resource->{name}, }); if($item) { - $c->log->error("email template with name '$$resource{name}' already exists for reseller_id '$$resource{reseller_id}'"); # TODO: user, message, trace, ... - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Email template with this name already exists for this reseller"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, + "Email template with this name already exists for this reseller", + "email template with name '$$resource{name}' already exists for reseller_id '$$resource{reseller_id}'"); last; } try { $item = $c->model('DB')->resultset('email_templates')->create($resource); } catch($e) { - $c->log->error("failed to create email template: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create email template."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create email template.", $e); last; } diff --git a/lib/NGCP/Panel/Controller/API/EmergencyMappingContainers.pm b/lib/NGCP/Panel/Controller/API/EmergencyMappingContainers.pm index f1137a1e61..e7f2c7fc21 100644 --- a/lib/NGCP/Panel/Controller/API/EmergencyMappingContainers.pm +++ b/lib/NGCP/Panel/Controller/API/EmergencyMappingContainers.pm @@ -126,8 +126,9 @@ sub POST :Allow { name => $resource->{name}, }); if($dup_item) { - $c->log->error("emergency mapping container with name '$$resource{name}' already exists for this reseller"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "emergency mapping container with this name already exists for this reseller"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, + "emergency mapping container with this name already exists for this reseller", + "emergency mapping container with name '$$resource{name}' already exists for this reseller"); return; } @@ -135,8 +136,7 @@ sub POST :Allow { try { $item = $schema->resultset('emergency_containers')->create($resource); } catch($e) { - $c->log->error("failed to create emergency mapping container: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create emergency mapping container."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create emergency mapping container.", $e); last; } diff --git a/lib/NGCP/Panel/Controller/API/EmergencyMappingContainersItem.pm b/lib/NGCP/Panel/Controller/API/EmergencyMappingContainersItem.pm index bd7aaa44c0..be741c71dc 100644 --- a/lib/NGCP/Panel/Controller/API/EmergencyMappingContainersItem.pm +++ b/lib/NGCP/Panel/Controller/API/EmergencyMappingContainersItem.pm @@ -124,8 +124,8 @@ sub DELETE :Allow { last unless $self->resource_exists($c, emergencymappingcontainer => $item); my $mapping_count = $item->emergency_mappings->count; if ($mapping_count > 0) { - $c->log->error("failed to delete emergency mapping container, there are still $mapping_count emergency mappings linked to it."); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to delete emergency mapping container."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to delete emergency mapping container.", + "failed to delete emergency mapping container, there are still $mapping_count emergency mappings linked to it."); last; } $item->delete; diff --git a/lib/NGCP/Panel/Controller/API/EmergencyMappings.pm b/lib/NGCP/Panel/Controller/API/EmergencyMappings.pm index 82a437df27..0e3bd9bc91 100644 --- a/lib/NGCP/Panel/Controller/API/EmergencyMappings.pm +++ b/lib/NGCP/Panel/Controller/API/EmergencyMappings.pm @@ -168,12 +168,10 @@ sub POST :Allow { $resource->{reseller_id} = $c->user->reseller_id; } else { unless(defined $resource->{reseller_id}) { - $c->log->error("Missing reseller_id"); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "missing reseller_id parameter"); last; } unless($schema->resultset('resellers')->find($resource->{reseller_id})) { - $c->log->error("Invalid reseller_id '$$resource{reseller_id}'"); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "invalid reseller_id '$$resource{reseller_id}'"); last; } @@ -204,8 +202,8 @@ sub POST :Allow { $c->response->body(q()); } catch($e) { - $c->log->error("failed to upload csv: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error"); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error", + "failed to upload csv", $e); last; }; } else { @@ -220,16 +218,17 @@ sub POST :Allow { my $container = $c->model('DB')->resultset('emergency_containers')->find($resource->{emergency_container_id}); unless($container) { - $c->log->error("invalid emergency container id '$$resource{emergency_container_id}'"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "emergency container id does not exist"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "emergency container id does not exist", + "invalid emergency container id '$$resource{emergency_container_id}'"); last; } if ($c->model('DB')->resultset('emergency_mappings')->search({ emergency_container_id => $container->id, code => $resource->{code} },undef)->count > 0) { - $c->log->error("Emergency mapping code '$$resource{code}' already defined for emergency container id '$$resource{emergency_container_id}'"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "emergency mapping code already exists for emergency container"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, + "Emergency mapping code already exists for emergency container", + "Emergency mapping code '$$resource{code}' already defined for emergency container id '$$resource{emergency_container_id}'"); last; } @@ -237,8 +236,7 @@ sub POST :Allow { try { $item = $c->model('DB')->resultset('emergency_mappings')->create($resource); } catch($e) { - $c->log->error("failed to create emergency mapping: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create emergency mapping."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create emergency mapping.", $e); last; } diff --git a/lib/NGCP/Panel/Controller/API/Faxes.pm b/lib/NGCP/Panel/Controller/API/Faxes.pm index c217ba3666..ace74f5293 100644 --- a/lib/NGCP/Panel/Controller/API/Faxes.pm +++ b/lib/NGCP/Panel/Controller/API/Faxes.pm @@ -94,23 +94,21 @@ sub create_item { my ($self, $c, $resource, $form, $process_extras) = @_; if (!$c->config->{features}->{faxserver}) { - $c->log->error("faxserver feature is not active."); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Faxserver feature is not active."); return; } my $billing_subscriber = NGCP::Panel::Utils::API::Subscribers::get_active_subscriber($self, $c, $resource->{subscriber_id}); unless($billing_subscriber) { - $c->log->error("invalid subscriber id $$resource{subscriber_id} for fax send"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Fax subscriber not found."); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Fax subscriber not found.", + "invalid subscriber id $$resource{subscriber_id} for fax send"); return; } my $prov_subscriber = $billing_subscriber->provisioning_voip_subscriber; return unless $prov_subscriber; my $faxpref = $prov_subscriber->voip_fax_preference; unless ($faxpref && $faxpref->active){ - $c->log->error("invalid subscriber fax preferences"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid subscriber fax preferences"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid subscriber fax preferences"); return; } try { @@ -125,8 +123,7 @@ sub create_item { $c->log->debug("faxserver output:\n"); $c->log->debug($output); } catch($e) { - $c->log->error("failed to send fax: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error"); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error", "failed to send fax", $e); return; }; return; diff --git a/lib/NGCP/Panel/Controller/API/FaxserverSettingsItem.pm b/lib/NGCP/Panel/Controller/API/FaxserverSettingsItem.pm index d476b8d8b3..3e0f0c9baa 100644 --- a/lib/NGCP/Panel/Controller/API/FaxserverSettingsItem.pm +++ b/lib/NGCP/Panel/Controller/API/FaxserverSettingsItem.pm @@ -36,8 +36,8 @@ sub update_item_model { my $billing_subscriber = NGCP::Panel::Utils::API::Subscribers::get_active_subscriber($self, $c, $item->id); unless($billing_subscriber) { - $c->log->error("invalid subscriber id $item->id for fax send"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Fax subscriber not found."); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Fax subscriber not found.", + "invalid subscriber id $item->id for fax send"); return; } delete $resource->{id}; @@ -67,8 +67,7 @@ sub update_item_model { $destinations_rs->create($dest); } } catch($e) { - $c->log->error("Error Updating faxserversettings: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "faxserversettings could not be updated."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "faxserversettings could not be updated.", $e); return; }; diff --git a/lib/NGCP/Panel/Controller/API/HeaderRuleActions.pm b/lib/NGCP/Panel/Controller/API/HeaderRuleActions.pm index 1eeab75b11..43da25ddd0 100644 --- a/lib/NGCP/Panel/Controller/API/HeaderRuleActions.pm +++ b/lib/NGCP/Panel/Controller/API/HeaderRuleActions.pm @@ -47,8 +47,7 @@ sub create_item { c => $c, set_id => $item->rule->ruleset->id ); } catch($e) { - $c->log->error("failed to create a header rule actions: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create a header rule actions."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create a header rule actions.", $e); return; } diff --git a/lib/NGCP/Panel/Controller/API/HeaderRuleConditions.pm b/lib/NGCP/Panel/Controller/API/HeaderRuleConditions.pm index f0ace6762d..189dc452c8 100644 --- a/lib/NGCP/Panel/Controller/API/HeaderRuleConditions.pm +++ b/lib/NGCP/Panel/Controller/API/HeaderRuleConditions.pm @@ -48,8 +48,7 @@ sub create_item { c => $c, set_id => $item->rule->ruleset->id ); } catch($e) { - $c->log->error("failed to create a header rule condition: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create a header rule condition."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create a header rule condition.", $e); return; } diff --git a/lib/NGCP/Panel/Controller/API/HeaderRuleSets.pm b/lib/NGCP/Panel/Controller/API/HeaderRuleSets.pm index 69fb916a8a..24a283a07c 100644 --- a/lib/NGCP/Panel/Controller/API/HeaderRuleSets.pm +++ b/lib/NGCP/Panel/Controller/API/HeaderRuleSets.pm @@ -95,8 +95,7 @@ sub create_item { ); } } catch($e) { - $c->log->error("failed to create a header rule set: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create a header rule set."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create a header rule set.", $e); return; } diff --git a/lib/NGCP/Panel/Controller/API/HeaderRules.pm b/lib/NGCP/Panel/Controller/API/HeaderRules.pm index fa6daf2a0f..e38c9dacdc 100644 --- a/lib/NGCP/Panel/Controller/API/HeaderRules.pm +++ b/lib/NGCP/Panel/Controller/API/HeaderRules.pm @@ -82,8 +82,7 @@ sub create_item { })->first; if ($existing_item) { - $c->log->error("header rule with name '$$resource{name}' already exists"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Header rule with this name already exists"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Header rule with this name already exists", "name=$$resource{name}"); return; } @@ -119,8 +118,7 @@ sub create_item { c => $c, set_id => $item->ruleset->id ); } catch($e) { - $c->log->error("failed to create a header rule: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create a header rule."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create a header rule.", $e); return; } diff --git a/lib/NGCP/Panel/Controller/API/Interceptions.pm b/lib/NGCP/Panel/Controller/API/Interceptions.pm index 558160dc1a..c5ad3f9149 100644 --- a/lib/NGCP/Panel/Controller/API/Interceptions.pm +++ b/lib/NGCP/Panel/Controller/API/Interceptions.pm @@ -139,8 +139,7 @@ sub POST :Allow { my ($sub, $reseller, $voip_number) = NGCP::Panel::Utils::Interception::subresnum_from_number($c, $resource->{number}, sub { my ($msg,$field,$response) = @_; - $c->log->error($msg); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, $response); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, $response, $msg); return 0; }); last unless($sub && $reseller); @@ -151,12 +150,10 @@ sub POST :Allow { $resource->{sip_domain} = $sub->domain->domain; if($resource->{x3_required} && (!defined $resource->{x3_host} || !defined $resource->{x3_port})) { - $c->log->error("Missing parameter 'x3_host' or 'x3_port' with 'x3_required' activated"); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Missing parameter 'x3_host' or 'x3_port' with 'x3_required' activated"); last; } if (defined $resource->{x3_port} && !is_int($resource->{x3_port})) { - $c->log->error("Parameter 'x3_port' should be an integer"); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Parameter 'x3_port' should be an integer"); last; } @@ -191,8 +188,7 @@ sub POST :Allow { }); die "Failed to populate capture agents\n" unless($res); } catch($e) { - $c->log->error("failed to create interception: " . $c->qs($e)); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create interception"); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create interception", $c->qs($e)); last; } diff --git a/lib/NGCP/Panel/Controller/API/InterceptionsItem.pm b/lib/NGCP/Panel/Controller/API/InterceptionsItem.pm index eec56ab285..4dedb1779b 100644 --- a/lib/NGCP/Panel/Controller/API/InterceptionsItem.pm +++ b/lib/NGCP/Panel/Controller/API/InterceptionsItem.pm @@ -156,7 +156,6 @@ sub DELETE :Allow { }); my $res = NGCP::Panel::Utils::Interception::request($c, 'DELETE', $uuid); unless($res) { - $c->log->error("failed to update capture agents"); $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to update capture agents"); last; } diff --git a/lib/NGCP/Panel/Controller/API/LnpCarriers.pm b/lib/NGCP/Panel/Controller/API/LnpCarriers.pm index 832b97dfd3..f56c28157d 100644 --- a/lib/NGCP/Panel/Controller/API/LnpCarriers.pm +++ b/lib/NGCP/Panel/Controller/API/LnpCarriers.pm @@ -116,8 +116,8 @@ sub POST :Allow { name => $resource->{name}, }); if($dup_item) { - $c->log->error("lnp carrier with name '$$resource{name}' already exists"); # TODO: user, message, trace, ... - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "LNP carrier with this name already exists"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "LNP carrier with this name already exists", + "lnp carrier with name '$$resource{name}' already exists"); return; } @@ -125,8 +125,7 @@ sub POST :Allow { try { $item = $schema->resultset('lnp_providers')->create($resource); } catch($e) { - $c->log->error("failed to create lnp carrier: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create lnp carrier."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create lnp carrier.", $e); last; } diff --git a/lib/NGCP/Panel/Controller/API/LnpCarriersItem.pm b/lib/NGCP/Panel/Controller/API/LnpCarriersItem.pm index a1d884758f..8beb01bdb5 100644 --- a/lib/NGCP/Panel/Controller/API/LnpCarriersItem.pm +++ b/lib/NGCP/Panel/Controller/API/LnpCarriersItem.pm @@ -123,8 +123,8 @@ sub DELETE :Allow { last unless $self->resource_exists($c, lnpcarrier => $item); my $number_count = $item->lnp_numbers->count; if ($number_count > 0) { - $c->log->error("failed to delete lnp carrier, there are still $number_count lnp numbers linked to it."); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to delete lnp carrier."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to delete lnp carrier.", + "failed to delete lnp carrier, there are still $number_count lnp numbers linked to it."); last; } $item->delete; diff --git a/lib/NGCP/Panel/Controller/API/LnpNumbers.pm b/lib/NGCP/Panel/Controller/API/LnpNumbers.pm index cfdfa132e5..1b88c3dd84 100644 --- a/lib/NGCP/Panel/Controller/API/LnpNumbers.pm +++ b/lib/NGCP/Panel/Controller/API/LnpNumbers.pm @@ -183,8 +183,8 @@ sub POST :Allow { $c->response->body(q()); } catch($e) { - $c->log->error("failed to upload csv: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error"); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error", + "failed to upload csv", $e); last; }; } else { @@ -208,8 +208,8 @@ sub POST :Allow { my $carrier = $c->model('DB')->resultset('lnp_providers')->find($resource->{lnp_provider_id}); unless($carrier) { - $c->log->error("invalid carrier_id '$$resource{lnp_provider_id}'"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "lnp carrier_id does not exist"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "lnp carrier_id does not exist", + "invalid carrier_id '$$resource{lnp_provider_id}'"); last; } # revert "MT#20027: the actual lnp number must be unique across lnp_providers" @@ -218,8 +218,7 @@ sub POST :Allow { try { $item = $c->model('DB')->resultset('lnp_numbers')->create($resource); } catch($e) { - $c->log->error("failed to create lnp number: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create lnp number."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create lnp number.", $e); last; } @@ -240,7 +239,6 @@ sub DELETE :Allow { my $guard = $c->model('DB')->txn_scope_guard; { unless (exists $c->req->query_params->{number}) { - $c->log->error("number query parameter required"); # TODO: user, message, trace, ... $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "number query parameter required."); last; } diff --git a/lib/NGCP/Panel/Controller/API/ManagerSecretaryItem.pm b/lib/NGCP/Panel/Controller/API/ManagerSecretaryItem.pm index 8e3020c44e..ab8079ff10 100644 --- a/lib/NGCP/Panel/Controller/API/ManagerSecretaryItem.pm +++ b/lib/NGCP/Panel/Controller/API/ManagerSecretaryItem.pm @@ -147,8 +147,8 @@ sub DELETE :Allow { try { $item = $self->update_item($c, $item, $old_resource, $resource, $form, $preference); } catch($e) { - $c->log->error("Failed to delete manager secretary callforward with id '$id': $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error"); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error", + "Failed to delete manager secretary callforward with id '$id'", $e); last; } diff --git a/lib/NGCP/Panel/Controller/API/NcosLevels.pm b/lib/NGCP/Panel/Controller/API/NcosLevels.pm index 7021725807..ebc478643c 100644 --- a/lib/NGCP/Panel/Controller/API/NcosLevels.pm +++ b/lib/NGCP/Panel/Controller/API/NcosLevels.pm @@ -133,8 +133,8 @@ sub POST :Allow { level => $resource->{level}, }); if($item) { - $c->log->error("ncos level '$$resource{level}' already exists for reseller_id '$$resource{reseller_id}'"); # TODO: user, message, trace, ... - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "NCOS level already exists for this reseller"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "NCOS level already exists for this reseller", + "ncos level '$$resource{level}' already exists for reseller_id '$$resource{reseller_id}'"); last; } @@ -145,7 +145,6 @@ sub POST :Allow { }); if (!$time_set) { my $err = "Time set with id '$resource->{time_set_id}' does not exist or does not belong to this reseller"; - $c->log->error($err); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, $err); last; } @@ -154,8 +153,7 @@ sub POST :Allow { try { $item = $c->model('DB')->resultset('ncos_levels')->create($resource); } catch($e) { - $c->log->error("failed to create ncos level: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create ncos level."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create ncos level.", $e); last; } diff --git a/lib/NGCP/Panel/Controller/API/NcosLnpCarriers.pm b/lib/NGCP/Panel/Controller/API/NcosLnpCarriers.pm index 00ae2ceb0b..0e52c211aa 100644 --- a/lib/NGCP/Panel/Controller/API/NcosLnpCarriers.pm +++ b/lib/NGCP/Panel/Controller/API/NcosLnpCarriers.pm @@ -128,8 +128,8 @@ sub POST :Allow { $resource->{ncos_level_id}, ); unless($level) { - $c->log->error("invalid ncos_level_id '$$resource{ncos_level_id}'"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid ncos_level_id, level does not exist"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid ncos_level_id, level does not exist", + "invalid ncos_level_id '$$resource{ncos_level_id}'"); return; } @@ -137,8 +137,9 @@ sub POST :Allow { lnp_provider_id => $resource->{lnp_provider_id}, })->first; if($dup_item) { - $c->log->error("ncos lnp entry with carrier '$$resource{lnp_provider_id}' already exists for ncos_level_id '$$resource{ncos_level_id}'"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "NCOS lnp entry already exists for given ncos level"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, + "NCOS lnp entry already exists for given ncos level", + "ncos lnp entry with carrier '$$resource{lnp_provider_id}' already exists for ncos_level_id '$$resource{ncos_level_id}'"); return; } @@ -146,8 +147,7 @@ sub POST :Allow { try { $item = $level->ncos_lnp_lists->create($resource); } catch($e) { - $c->log->error("failed to create ncos lnp entry: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create ncos lnp entry."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create ncos lnp entry.", $e); last; } diff --git a/lib/NGCP/Panel/Controller/API/NcosLnpPatterns.pm b/lib/NGCP/Panel/Controller/API/NcosLnpPatterns.pm index 5f727a8b3e..956636868c 100644 --- a/lib/NGCP/Panel/Controller/API/NcosLnpPatterns.pm +++ b/lib/NGCP/Panel/Controller/API/NcosLnpPatterns.pm @@ -111,15 +111,14 @@ sub create_item { }); my $lnp_list = $lnp_list_rs->first; unless($lnp_list) { - $c->log->error("invalid ncos_lnp_list_id '$$resource{ncos_lnp_list_id}'"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid ncos_lnp_list_id, lnp list does not exist"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid ncos_lnp_list_id, lnp list does not exist", + "invalid ncos_lnp_list_id '$$resource{ncos_lnp_list_id}'"); return; } $item = $lnp_list->ncos_lnp_pattern_lists->create($resource); } catch($e) { - $c->log->error("failed to create a ncos lnp carrier pattern: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create a ncos lnp carrier pattern."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create a ncos lnp carrier pattern.", $e); return; } diff --git a/lib/NGCP/Panel/Controller/API/NcosPatterns.pm b/lib/NGCP/Panel/Controller/API/NcosPatterns.pm index 8870ebfc39..f4c33ab73b 100644 --- a/lib/NGCP/Panel/Controller/API/NcosPatterns.pm +++ b/lib/NGCP/Panel/Controller/API/NcosPatterns.pm @@ -129,8 +129,8 @@ sub POST :Allow { } my $level = $level_rs->first; unless($level) { - $c->log->error("invalid ncos_level_id '$$resource{ncos_level_id}' for reseller_id '$$resource{reseller_id}'"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid ncos_level_id, level does not exist"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid ncos_level_id, level does not exist", + "invalid ncos_level_id '$$resource{ncos_level_id}' for reseller_id '$$resource{reseller_id}'"); return; } @@ -138,8 +138,8 @@ sub POST :Allow { pattern => $resource->{pattern}, })->first; if($dup_item) { - $c->log->error("ncos pattern '$$resource{pattern}' already exists for ncos_level_id '$$resource{ncos_level_id}'"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "NCOS pattern already exists for given ncos level"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "NCOS pattern already exists for given ncos level", + "ncos pattern '$$resource{pattern}' already exists for ncos_level_id '$$resource{ncos_level_id}'"); return; } @@ -147,8 +147,7 @@ sub POST :Allow { try { $item = $level->ncos_pattern_lists->create($resource); } catch($e) { - $c->log->error("failed to create ncos level: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create ncos level."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create ncos level.", $e); last; } diff --git a/lib/NGCP/Panel/Controller/API/NumbersItem.pm b/lib/NGCP/Panel/Controller/API/NumbersItem.pm index f1c6b22afa..f2b7df0175 100644 --- a/lib/NGCP/Panel/Controller/API/NumbersItem.pm +++ b/lib/NGCP/Panel/Controller/API/NumbersItem.pm @@ -174,8 +174,7 @@ sub update_item_model { ); } catch($e) { - $c->log->error("failed to update number: " . $c->qs($e)); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to update number."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to update number.", $c->qs($e)); return; } diff --git a/lib/NGCP/Panel/Controller/API/PartyCallControls.pm b/lib/NGCP/Panel/Controller/API/PartyCallControls.pm index 3ed9fd4121..87ae617ca1 100644 --- a/lib/NGCP/Panel/Controller/API/PartyCallControls.pm +++ b/lib/NGCP/Panel/Controller/API/PartyCallControls.pm @@ -87,15 +87,13 @@ sub POST :Allow { })->first; } } catch($e) { - $c->log->error("failed to handle a party call control request: $e"); $self->error($c, HTTP_INTERNAL_SERVER_ERROR, - "Failed to handle a party call control request."); + "Failed to handle a party call control request.", $e); last; } unless($sms) { - $c->log->error("failed to find sms with id " . $c->qs($callid) . " and token $token"); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, - "Failed to find sms with callid " . $c->qs($callid) . " and given token"); + "Failed to find sms with callid " . $c->qs($callid) . " and given token", $token); last; } if($status eq "ACCEPT") { @@ -120,9 +118,8 @@ sub POST :Allow { ); $sms->update({ pcc_status => "complete" }); } catch($e) { - $c->log->error("failed to handle a party call control request: $e"); $self->error($c, HTTP_INTERNAL_SERVER_ERROR, - "Failed to handle a party call control request."); + "Failed to handle a party call control request.", $e); last; } } else { @@ -130,9 +127,8 @@ sub POST :Allow { try { $sms->update({ pcc_status => "complete" }); } catch($e) { - $c->log->error("failed to handle a party call control request: $e"); $self->error($c, HTTP_INTERNAL_SERVER_ERROR, - "Failed to handle a party call control request."); + "Failed to handle a party call control request.", $e); last; } } diff --git a/lib/NGCP/Panel/Controller/API/PasswordRecovery.pm b/lib/NGCP/Panel/Controller/API/PasswordRecovery.pm index 9cbd915bf5..59d0769765 100644 --- a/lib/NGCP/Panel/Controller/API/PasswordRecovery.pm +++ b/lib/NGCP/Panel/Controller/API/PasswordRecovery.pm @@ -75,9 +75,8 @@ sub POST :Allow { unless($uuid_string && UUID::parse($uuid_string, $uuid_bin) != -1) { $res = {success => 0}; - $c->log->error("Invalid password recovery attempt for token '$uuid_string' from '".$c->qs($c->req->address)."'"); - $c->response->status(HTTP_FORBIDDEN); - $c->response->body(JSON::to_json($res)); + $self->error($c, HTTP_FORBIDDEN, 'Forbidden', + "Invalid password recovery attempt for token '$uuid_string' from '".$c->qs($c->req->address)."'"); return; } @@ -88,9 +87,8 @@ sub POST :Allow { ); unless ($redis) { $res = {success => 0}; - $c->log->error("Failed to connect to central redis url " . $c->config->{redis}->{central_url}); - $c->response->status(HTTP_INTERNAL_SERVER_ERROR); - $c->response->body(JSON::to_json($res)); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, 'Internal Server Error', + "Failed to connect to central redis url " . $c->config->{redis}->{central_url}); return; } $redis->select($c->config->{'Plugin::Session'}->{redis_db}); @@ -100,17 +98,15 @@ sub POST :Allow { my $administrator = $c->model('DB')->resultset('admins')->search({login => $admin})->first; unless ($administrator) { $res = {success => 0}; - $c->log->error("Invalid password recovery attempt for token '$uuid_string' from '".$c->qs($c->req->address)."'"); - $c->response->status(HTTP_FORBIDDEN); - $c->response->body(JSON::to_json($res)); + $self->error($c, HTTP_FORBIDDEN, 'Forbidden', + "Invalid password recovery attempt for token '$uuid_string' from '".$c->qs($c->req->address)."'"); return; } my $ip = $redis->hget("password_reset:admin::$uuid_string", "ip"); if ($ip && $ip ne $c->req->address) { $res = {success => 0}; - $c->log->error("Invalid password recovery attempt for token '$uuid_string' from '".$c->qs($c->req->address)."'"); - $c->response->status(HTTP_FORBIDDEN); - $c->response->body(JSON::to_json($res)); + $self->error($c, HTTP_FORBIDDEN, 'Forbidden', + "Invalid password recovery attempt for token '$uuid_string' from '".$c->qs($c->req->address)."'"); return; } $c->log->debug("Updating administrator password."); @@ -130,9 +126,8 @@ sub POST :Allow { my $subscriber = $rs->first ? $rs->first->voip_subscriber : undef; unless($subscriber && $subscriber->provisioning_voip_subscriber) { $res = {success => 0}; - $c->log->error("Invalid password recovery attempt for token '$uuid_string' from '".$c->qs($c->req->address)."'"); - $c->response->status(HTTP_FORBIDDEN); - $c->response->body(JSON::to_json($res)); + $self->error($c, HTTP_FORBIDDEN, 'Forbidden', + "Invalid password recovery attempt for token '$uuid_string' from '".$c->qs($c->req->address)."'"); return; } $c->log->debug("Updating subscriber password."); diff --git a/lib/NGCP/Panel/Controller/API/PbxDeviceConfigs.pm b/lib/NGCP/Panel/Controller/API/PbxDeviceConfigs.pm index f9c5f095c4..672f07887e 100644 --- a/lib/NGCP/Panel/Controller/API/PbxDeviceConfigs.pm +++ b/lib/NGCP/Panel/Controller/API/PbxDeviceConfigs.pm @@ -146,8 +146,8 @@ sub POST :Allow { } my $model = $model_rs->first; unless($model) { - $c->log->error("invalid device_id '$$resource{device_id}'"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Pbx device model does not exist"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Pbx device model does not exist", + "invalid device_id '$$resource{device_id}'"); last; } @@ -158,8 +158,7 @@ sub POST :Allow { try { $item = $model->autoprov_configs->create($resource); } catch($e) { - $c->log->error("failed to create pbxdeviceconfig: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create pbxdeviceconfig."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create pbxdeviceconfig.", $e); last; } diff --git a/lib/NGCP/Panel/Controller/API/PbxDeviceFirmwares.pm b/lib/NGCP/Panel/Controller/API/PbxDeviceFirmwares.pm index 3e812f8f4e..d3fd4f4548 100644 --- a/lib/NGCP/Panel/Controller/API/PbxDeviceFirmwares.pm +++ b/lib/NGCP/Panel/Controller/API/PbxDeviceFirmwares.pm @@ -147,8 +147,8 @@ sub POST :Allow { } my $model = $model_rs->first; unless($model) { - $c->log->error("invalid device_id '$$resource{device_id}'"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Pbx device model does not exist"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Pbx device model does not exist", + "invalid device_id '$$resource{device_id}'"); last; } @@ -163,8 +163,7 @@ sub POST :Allow { ); } } catch($e) { - $c->log->error("failed to create pbxdevicefirmware: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create pbxdevicefirmware."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create pbxdevicefirmware.", $e); last; } diff --git a/lib/NGCP/Panel/Controller/API/PbxDeviceProfiles.pm b/lib/NGCP/Panel/Controller/API/PbxDeviceProfiles.pm index baaf0a21bc..69e8216984 100644 --- a/lib/NGCP/Panel/Controller/API/PbxDeviceProfiles.pm +++ b/lib/NGCP/Panel/Controller/API/PbxDeviceProfiles.pm @@ -98,8 +98,8 @@ sub POST :Allow { my ($self, $c) = @_; if ($c->user->roles eq 'subscriberadmin') { - $c->log->error("role subscriberadmin cannot create pbxdeviceprofiles"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid role. Cannot create pbxdeviceprofile."); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid role. Cannot create pbxdeviceprofile.", + "role subscriberadmin cannot create pbxdeviceprofiles"); return; } @@ -124,8 +124,9 @@ sub POST :Allow { name => $resource->{name}, }); if($item) { - $c->log->error("Pbx device profile with name '$$resource{name}' already exists for config_id '$$resource{config_id}'"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Pbx device profile with this name already exists for this config"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, + "Pbx device profile with this name already exists for this config", + "Pbx device profile with name '$$resource{name}' already exists for config_id '$$resource{config_id}'"); last; } my $config_rs = $c->model('DB')->resultset('autoprov_configs')->search({ @@ -141,16 +142,15 @@ sub POST :Allow { } my $config = $config_rs->first; unless($config) { - $c->log->error("Pbx device config with confg_id '$$resource{config_id}' does not exist"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Pbx device config does not exist"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Pbx device config does not exist", + "Pbx device config with confg_id '$$resource{config_id}' does not exist"); last; } try { $item = $config->autoprov_profiles->create($resource); } catch($e) { - $c->log->error("failed to create pbx device profile: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create pbx device profile."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create pbx device profile.", $e); last; } diff --git a/lib/NGCP/Panel/Controller/API/PbxDeviceProfilesItem.pm b/lib/NGCP/Panel/Controller/API/PbxDeviceProfilesItem.pm index 62c2ed8838..5d2d773489 100644 --- a/lib/NGCP/Panel/Controller/API/PbxDeviceProfilesItem.pm +++ b/lib/NGCP/Panel/Controller/API/PbxDeviceProfilesItem.pm @@ -62,7 +62,6 @@ sub PATCH :Allow { my ($self, $c, $id) = @_; if ($c->user->roles eq 'subscriberadmin') { - $c->log->error("role subscriberadmin cannot edit pbxdeviceprofiles"); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid role. Cannot edit pbxdeviceprofile."); return; } @@ -100,7 +99,6 @@ sub PUT :Allow { my ($self, $c, $id) = @_; if ($c->user->roles eq 'subscriberadmin') { - $c->log->error("role subscriberadmin cannot edit pbxdeviceprofiles"); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid role. Cannot edit pbxdeviceprofile."); return; } diff --git a/lib/NGCP/Panel/Controller/API/PbxDevices.pm b/lib/NGCP/Panel/Controller/API/PbxDevices.pm index d8066b52a9..bf1140a754 100644 --- a/lib/NGCP/Panel/Controller/API/PbxDevices.pm +++ b/lib/NGCP/Panel/Controller/API/PbxDevices.pm @@ -281,8 +281,7 @@ sub POST :Allow { $device->autoprov_field_device_lines->create($line); } } catch($e) { - $c->log->error("failed to create pbxdevice: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create pbxdevice."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create pbxdevice.", $e); last; }; diff --git a/lib/NGCP/Panel/Controller/API/PbxDevicesItem.pm b/lib/NGCP/Panel/Controller/API/PbxDevicesItem.pm index 7a25dc3371..a5518eb8e4 100644 --- a/lib/NGCP/Panel/Controller/API/PbxDevicesItem.pm +++ b/lib/NGCP/Panel/Controller/API/PbxDevicesItem.pm @@ -152,8 +152,8 @@ sub DELETE :Allow { NGCP::Panel::Utils::DeviceBootstrap::dispatch($c, 'unregister', $device, $device->identifier); $device->delete; } catch($e) { - $c->log->error("Failed to delete pbx field device with id '$id': $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error"); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error", + "Failed to delete pbx field device with id '$id'", $e); last; } $guard->commit; diff --git a/lib/NGCP/Panel/Controller/API/PeeringGroups.pm b/lib/NGCP/Panel/Controller/API/PeeringGroups.pm index 44a7acf985..1672f30c20 100644 --- a/lib/NGCP/Panel/Controller/API/PeeringGroups.pm +++ b/lib/NGCP/Panel/Controller/API/PeeringGroups.pm @@ -12,6 +12,10 @@ use HTTP::Status qw(:constants); use NGCP::Panel::Utils::Peering; use parent qw/NGCP::Panel::Role::Entities NGCP::Panel::Role::API::PeeringGroups/;#Catalyst::Controller +__PACKAGE__->set_config({ + own_transaction_control => { POST => 1 }, +}); + sub allowed_methods{ return [qw/GET POST OPTIONS HEAD/]; } @@ -81,55 +85,32 @@ sub GET :Allow { return; } -sub POST :Allow { - my ($self, $c) = @_; +sub create_item { + my ($self, $c, $resource, $form, $process_extras) = @_; + my $item; my $guard = $c->model('DB')->txn_scope_guard; - { - my $resource = $self->get_valid_post_data( - c => $c, - media_type => 'application/json', - ); - last unless $resource; - - my $form = $self->get_form($c); - - last unless $self->validate_form( - c => $c, - resource => $resource, - form => $form, - ); - last unless $resource; - - $resource = $self->process_form_resource($c, undef, undef, $resource, $form); - - my $item; + try { my $dup_item = $c->model('DB')->resultset('voip_peer_groups')->find({ name => $resource->{name}, }); - if($dup_item) { - $c->log->error("peering group with name '$$resource{name}' already exists"); # TODO: user, message, trace, ... - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Peering group with this name already exists"); - last; - } - try { - $item = $c->model('DB')->resultset('voip_peer_groups')->create($resource); - } catch($e){ - $c->log->error("failed to create peering group: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create peering group."); - last; + if ($dup_item) { + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Peering group with this name already exists", + "peering group with name '$$resource{name}' already exists"); + return; } - $guard->commit; + $item = $c->model('DB')->resultset('voip_peer_groups')->create($resource); - NGCP::Panel::Utils::Peering::_sip_lcr_reload(c => $c); + $guard->commit; - $c->response->status(HTTP_CREATED); - $c->response->header(Location => sprintf('/%s%d', $c->request->path, $item->id)); - $c->response->body(q()); + } catch($e) { + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create peering group.", $e); + return; } - return; + NGCP::Panel::Utils::Peering::_sip_lcr_reload(c => $c); + return $item; } 1; diff --git a/lib/NGCP/Panel/Controller/API/PeeringInboundRules.pm b/lib/NGCP/Panel/Controller/API/PeeringInboundRules.pm index 7c0cdc1ef3..1311c6a4f9 100644 --- a/lib/NGCP/Panel/Controller/API/PeeringInboundRules.pm +++ b/lib/NGCP/Panel/Controller/API/PeeringInboundRules.pm @@ -129,7 +129,6 @@ sub POST :Allow { form => $form, ); unless($c->model('DB')->resultset('voip_peer_groups')->find($resource->{group_id})) { - $c->log->error("peering group $$resource{group_id} does not exist"); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "peering group $$resource{group_id} does not exist"); last; } @@ -143,7 +142,6 @@ sub POST :Allow { priority => $resource->{priority}, }); if($dup_item) { - $c->log->error("peering rule already exists"); # TODO: user, message, trace, ... $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "peering rule already exists"); last; } @@ -154,7 +152,6 @@ sub POST :Allow { {} ); if($prio_rs->count) { - $c->log->error("peering rule priority $$resource{priority} already exists for this group"); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "peering rule priority $$resource{priority} already exists for this group"); last; } @@ -165,8 +162,7 @@ sub POST :Allow { has_inbound_rules => 1 }); } catch($e) { - $c->log->error("failed to create peering rule: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create peering rule."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create peering rule.", $e); last; } diff --git a/lib/NGCP/Panel/Controller/API/PeeringRules.pm b/lib/NGCP/Panel/Controller/API/PeeringRules.pm index 7b1bb1df84..acc97af930 100644 --- a/lib/NGCP/Panel/Controller/API/PeeringRules.pm +++ b/lib/NGCP/Panel/Controller/API/PeeringRules.pm @@ -141,7 +141,6 @@ sub POST :Allow { }); if ($dup_item) { - $c->log->error("peering rule already exists"); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "peering rule already exists"); return; } @@ -149,8 +148,7 @@ sub POST :Allow { try { $item = $c->model('DB')->resultset('voip_peer_rules')->create($resource); } catch($e) { - $c->log->error("failed to create peering rule: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create peering rule."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create peering rule.", $e); last; } diff --git a/lib/NGCP/Panel/Controller/API/PeeringServers.pm b/lib/NGCP/Panel/Controller/API/PeeringServers.pm index 5f1c98adfa..db701525ae 100644 --- a/lib/NGCP/Panel/Controller/API/PeeringServers.pm +++ b/lib/NGCP/Panel/Controller/API/PeeringServers.pm @@ -142,8 +142,8 @@ sub POST :Allow { name => $resource->{name}, }); if($dup_item) { - $c->log->error("peering server with name '$$resource{name}' already exists"); # TODO: user, message, trace, ... - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "peering server with this name already exists"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "peering server with this name already exists", + "peering server with name '$$resource{name}' already exists"); return; } @@ -153,8 +153,7 @@ sub POST :Allow { NGCP::Panel::Utils::Peering::_sip_dispatcher_reload(c => $c); } } catch($e) { - $c->log->error("failed to create peering server: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create peering server."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create peering server.", $e); last; } @@ -167,8 +166,8 @@ sub POST :Allow { NGCP::Panel::Utils::Peering::_sip_dispatcher_reload(c => $c); } } catch($e) { - $c->log->error("failed to reload kamailio cache: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create peering server."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create peering server.", + "failed to reload kamailio cache", $e); last; } diff --git a/lib/NGCP/Panel/Controller/API/PeeringServersItem.pm b/lib/NGCP/Panel/Controller/API/PeeringServersItem.pm index 2757942415..93e875cfe2 100644 --- a/lib/NGCP/Panel/Controller/API/PeeringServersItem.pm +++ b/lib/NGCP/Panel/Controller/API/PeeringServersItem.pm @@ -94,8 +94,8 @@ sub PATCH :Allow { } NGCP::Panel::Utils::Peering::_sip_dispatcher_reload(c => $c); } catch($e) { - $c->log->error("failed to reload kamailio cache: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create peering server."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create peering server.", + "failed to reload kamailio cache", $e); last; } @@ -152,8 +152,8 @@ sub PUT :Allow { } NGCP::Panel::Utils::Peering::_sip_dispatcher_reload(c => $c); } catch($e) { - $c->log->error("failed to reload kamailio cache: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create peering server."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create peering server.", + "failed to reload kamailio cache", $e); last; } @@ -198,8 +198,8 @@ sub DELETE :Allow { NGCP::Panel::Utils::Peering::_sip_dispatcher_reload(c => $c); } } catch($e) { - $c->log->error("failed to reload kamailio cache: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create peering server."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create peering server.", + "failed to reload kamailio cache", $e); last; } diff --git a/lib/NGCP/Panel/Controller/API/ProfilePackages.pm b/lib/NGCP/Panel/Controller/API/ProfilePackages.pm index df24a1b570..3e269c803b 100644 --- a/lib/NGCP/Panel/Controller/API/ProfilePackages.pm +++ b/lib/NGCP/Panel/Controller/API/ProfilePackages.pm @@ -170,7 +170,6 @@ sub POST :Allow { mappings_to_create => $mappings_to_create, err_code => sub { my ($err) = @_; - #$c->log->error($err); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, $err); }); @@ -181,8 +180,7 @@ sub POST :Allow { $profile_package->profiles->create($mapping); } } catch($e) { - $c->log->error("failed to create profile package: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create profile package."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create profile package.", $e); last; } diff --git a/lib/NGCP/Panel/Controller/API/ProvisioningTemplatesItem.pm b/lib/NGCP/Panel/Controller/API/ProvisioningTemplatesItem.pm index 9c93154624..7719cd83ee 100644 --- a/lib/NGCP/Panel/Controller/API/ProvisioningTemplatesItem.pm +++ b/lib/NGCP/Panel/Controller/API/ProvisioningTemplatesItem.pm @@ -372,11 +372,7 @@ sub post { $c->response->header(Location => sprintf('%s%d', NGCP::Panel::Role::API::Subscribers::dispatch_path(), $context->{subscriber}->{id})); } catch($e) { NGCP::Panel::Utils::ProvisioningTemplates::provision_cleanup($c, $context); - $c->log->error(sprintf("Provisioning template '%s' failed: %s", - $id, - $e, - )); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, $e); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Provisioning template '$id' failed", $e); return; } } else { @@ -387,15 +383,15 @@ sub post { purge => $purge, ); if (scalar @$errors) { - $c->log->error(sprintf('CSV file (%d lines) processed, %d error(s).', $linecount, scalar @$errors)); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error"); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error", + sprintf('CSV file (%d lines) processed, %d error(s).', $linecount, scalar @$errors)); return; } else { $c->log->debug(sprintf('CSV file (%d lines) processed, %d error(s).', $linecount, 0)); } } catch($e) { - $c->log->error("failed to process CSV file: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error"); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error", + "failed to process CSV file", $e); return; } } diff --git a/lib/NGCP/Panel/Controller/API/Reminders.pm b/lib/NGCP/Panel/Controller/API/Reminders.pm index de25d11bab..c2d5d28f3f 100644 --- a/lib/NGCP/Panel/Controller/API/Reminders.pm +++ b/lib/NGCP/Panel/Controller/API/Reminders.pm @@ -140,8 +140,8 @@ sub POST :Allow { pref_list => ['reminder'], ); unless ($allowed_prefs->{reminder}) { - $c->log->error("Not permitted to create reminder for this subscriber via subscriber profile"); - $self->error($c, HTTP_FORBIDDEN, "Not permitted to create reminder"); + $self->error($c, HTTP_FORBIDDEN, "Not permitted to create reminder", + "Not permitted to create reminder for this subscriber via subscriber profile"); return; } @@ -150,16 +150,15 @@ sub POST :Allow { subscriber_id => $resource->{subscriber_id}, }); if($item) { - $c->log->error("reminder already exists for subscriber_id '$$resource{subscriber_id}'"); # TODO: user, message, trace, ... - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Reminder already exists for this subscriber"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Reminder already exists for this subscriber", + "reminder already exists for subscriber_id '$$resource{subscriber_id}'"); last; } try { $item = $c->model('DB')->resultset('voip_reminder')->create($resource); } catch($e) { - $c->log->error("failed to create reminder: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create reminder."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create reminder.", $e); last; } diff --git a/lib/NGCP/Panel/Controller/API/Resellers.pm b/lib/NGCP/Panel/Controller/API/Resellers.pm index 2082dfa783..2390e181d7 100644 --- a/lib/NGCP/Panel/Controller/API/Resellers.pm +++ b/lib/NGCP/Panel/Controller/API/Resellers.pm @@ -163,8 +163,7 @@ sub POST :Allow { }); NGCP::Panel::Utils::Reseller::create_email_templates( c => $c, reseller => $reseller ); } catch($e) { - $c->log->error("failed to create reseller: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create reseller."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create reseller.", $e); last; } diff --git a/lib/NGCP/Panel/Controller/API/RewriteRuleSets.pm b/lib/NGCP/Panel/Controller/API/RewriteRuleSets.pm index 260aa51eca..2a825fe05d 100644 --- a/lib/NGCP/Panel/Controller/API/RewriteRuleSets.pm +++ b/lib/NGCP/Panel/Controller/API/RewriteRuleSets.pm @@ -45,21 +45,19 @@ sub create_item { my $schema = $c->model('DB'); my $item; my $guard = $schema->txn_scope_guard; - { + try { my $rewriterules = delete $resource->{rewriterules}; - try { - $item = $schema->resultset('voip_rewrite_rule_sets')->create($resource); - } catch($e) { - $c->log->error("failed to create rewriteruleset: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create rewriteruleset."); - return; - } + $item = $schema->resultset('voip_rewrite_rule_sets')->create($resource); if ($rewriterules) { $self->update_rewriterules( $c, $item, $form, $rewriterules ); } - $guard->commit; - NGCP::Panel::Utils::Rewrite::sip_dialplan_reload($c); + } catch($e) { + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create rewriteruleset.", $e); + return; } + $guard->commit; + NGCP::Panel::Utils::Rewrite::sip_dialplan_reload($c); + return $item; } diff --git a/lib/NGCP/Panel/Controller/API/RewriteRuleSetsItem.pm b/lib/NGCP/Panel/Controller/API/RewriteRuleSetsItem.pm index 0a62248d79..b815acc4d8 100644 --- a/lib/NGCP/Panel/Controller/API/RewriteRuleSetsItem.pm +++ b/lib/NGCP/Panel/Controller/API/RewriteRuleSetsItem.pm @@ -24,8 +24,8 @@ sub delete_item { $item->voip_rewrite_rules->delete; $item->delete; } catch($e) { - $c->log->error("Failed to delete rewriteruleset with id '".$item->id."': $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error"); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error", + "Failed to delete rewriteruleset with id '".$item->id."'", $e); last; } $guard->commit; @@ -48,8 +48,8 @@ sub update_item_model { $self->update_rewriterules( $c, $item, $form, $rewriterules ); } } catch($e) { - $c->log->error("Failed to update rewriterule with id '$id': $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error"); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error", + "Failed to update rewriterule with id '$id'", $e); die; } $guard->commit; diff --git a/lib/NGCP/Panel/Controller/API/RewriteRules.pm b/lib/NGCP/Panel/Controller/API/RewriteRules.pm index efa0c7c6e7..499912547a 100644 --- a/lib/NGCP/Panel/Controller/API/RewriteRules.pm +++ b/lib/NGCP/Panel/Controller/API/RewriteRules.pm @@ -80,8 +80,7 @@ sub create_item { } $item = $schema->resultset('voip_rewrite_rules')->create($resource); } catch($e) { - $c->log->error("failed to create rewriterule: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create rewriterule."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create rewriterule.", $e); return; } $guard->commit; diff --git a/lib/NGCP/Panel/Controller/API/RewriteRulesItem.pm b/lib/NGCP/Panel/Controller/API/RewriteRulesItem.pm index e0c1e019cd..dbb30936a7 100644 --- a/lib/NGCP/Panel/Controller/API/RewriteRulesItem.pm +++ b/lib/NGCP/Panel/Controller/API/RewriteRulesItem.pm @@ -21,8 +21,8 @@ sub delete_item { try { $item->delete; } catch($e) { - $c->log->error("Failed to delete rewriterule with id '".$item->id."': $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error"); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error", + "Failed to delete rewriterule with id '".$item->id."'", $e); return; } $guard->commit; @@ -41,8 +41,8 @@ sub update_item_model { try { $item->update($resource); } catch($e) { - $c->log->error("Failed to update rewriterule with id '$id': $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error"); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error", + "Failed to update rewriterule with id '$id'", $e); die; } $guard->commit; diff --git a/lib/NGCP/Panel/Controller/API/SMS.pm b/lib/NGCP/Panel/Controller/API/SMS.pm index 53de75c0b8..e5a92daad5 100644 --- a/lib/NGCP/Panel/Controller/API/SMS.pm +++ b/lib/NGCP/Panel/Controller/API/SMS.pm @@ -167,12 +167,11 @@ sub create_item { die $session->{reason}."\n"; } } catch($e) { - $c->log->error($e); if ($session && $session->{reason} eq 'insufficient credit') { - $self->error($c, HTTP_PAYMENT_REQUIRED, "Not enough credit to send the sms"); + $self->error($c, HTTP_PAYMENT_REQUIRED, "Not enough credit to send the sms", $e); } else { $self->error($c, HTTP_INTERNAL_SERVER_ERROR, - "An internal error has occurred when sending the sms, please contact the platform administrator or try again later"); + "An internal error has occurred when sending the sms, please contact the platform administrator or try again later", $e); } } diff --git a/lib/NGCP/Panel/Controller/API/SoundSets.pm b/lib/NGCP/Panel/Controller/API/SoundSets.pm index b0a2924944..10513ab492 100644 --- a/lib/NGCP/Panel/Controller/API/SoundSets.pm +++ b/lib/NGCP/Panel/Controller/API/SoundSets.pm @@ -78,8 +78,7 @@ sub create_item { ); } } catch($e) { - $c->log->error("failed to create soundset: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create soundset."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create soundset.", $e); return; } diff --git a/lib/NGCP/Panel/Controller/API/SoundSetsItem.pm b/lib/NGCP/Panel/Controller/API/SoundSetsItem.pm index 14101de8f1..24f4cc33a7 100644 --- a/lib/NGCP/Panel/Controller/API/SoundSetsItem.pm +++ b/lib/NGCP/Panel/Controller/API/SoundSetsItem.pm @@ -66,8 +66,8 @@ sub delete_item { if ($c->user->roles eq 'subscriberadmin' && (!$item->contract_id || $item->contract_id != $c->user->account_id)) { - $c->log->error("Cannot modify read-only sound set that does not belong to this subscriberadmin"); - $self->error($c, HTTP_FORBIDDEN, "Cannot modify read-only sound set"); + $self->error($c, HTTP_FORBIDDEN, "Cannot modify read-only sound set", + "does not belong to this subscriberadmin"); return; } diff --git a/lib/NGCP/Panel/Controller/API/SubscriberLocationMappings.pm b/lib/NGCP/Panel/Controller/API/SubscriberLocationMappings.pm index 54637e7bf6..d06f1c2581 100644 --- a/lib/NGCP/Panel/Controller/API/SubscriberLocationMappings.pm +++ b/lib/NGCP/Panel/Controller/API/SubscriberLocationMappings.pm @@ -130,8 +130,8 @@ sub POST :Allow { } my $sub = $sub_rs->first; unless($sub && $sub->provisioning_voip_subscriber) { - $c->log->error("invalid subscriber_id '$$resource{subscriber_id}'"); # TODO: user, message, trace, ... - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Subscriber does not exist"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Subscriber does not exist", + "invalid subscriber_id '$$resource{subscriber_id}'"); last; } @@ -144,8 +144,7 @@ sub POST :Allow { try { $item = $c->model('DB')->resultset('voip_subscriber_location_mappings')->create($resource); } catch($e) { - $c->log->error("failed to create location mapping: " . $c->qs($e)); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create location mapping."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create location mapping.", $c->qs($e)); last; } diff --git a/lib/NGCP/Panel/Controller/API/SubscriberProfileSets.pm b/lib/NGCP/Panel/Controller/API/SubscriberProfileSets.pm index 899614d58e..a24f2f3ba1 100644 --- a/lib/NGCP/Panel/Controller/API/SubscriberProfileSets.pm +++ b/lib/NGCP/Panel/Controller/API/SubscriberProfileSets.pm @@ -110,8 +110,8 @@ sub POST :Allow { } if($c->user->roles eq "reseller" && !$c->config->{profile_sets}->{reseller_edit}) { - $c->log->error("profile set creation by reseller forbidden via config"); - $self->error($c, HTTP_FORBIDDEN, "Subscriber profile set creation forbidden for resellers."); + $self->error($c, HTTP_FORBIDDEN, "Subscriber profile set creation forbidden for resellers.", + "profile set creation by reseller forbidden via config"); return; } @@ -141,16 +141,16 @@ sub POST :Allow { name => $resource->{name}, }); if($item) { - $c->log->error("subscriber profile set with name '$$resource{name}' already exists for reseller_id '$$resource{reseller_id}'"); # TODO: user, message, trace, ... - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Subscriber profile set with this name already exists for this reseller"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, + "Subscriber profile set with this name already exists for this reseller", + "subscriber profile set with name '$$resource{name}' already exists for reseller_id '$$resource{reseller_id}'"); last; } try { $item = $c->model('DB')->resultset('voip_subscriber_profile_sets')->create($resource); } catch($e) { - $c->log->error("failed to create subscriber profile set: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create subscriber profile set."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create subscriber profile set.", $e); last; } diff --git a/lib/NGCP/Panel/Controller/API/SubscriberProfileSetsItem.pm b/lib/NGCP/Panel/Controller/API/SubscriberProfileSetsItem.pm index 0d2dcc5374..033f32665d 100644 --- a/lib/NGCP/Panel/Controller/API/SubscriberProfileSetsItem.pm +++ b/lib/NGCP/Panel/Controller/API/SubscriberProfileSetsItem.pm @@ -72,8 +72,8 @@ sub PATCH :Allow { } if($c->user->roles eq "reseller" && !$c->config->{profile_sets}->{reseller_edit}) { - $c->log->error("profile set modification by reseller forbidden via config"); - $self->error($c, HTTP_FORBIDDEN, "Subscriber profile set modification forbidden for resellers."); + $self->error($c, HTTP_FORBIDDEN, "Subscriber profile set modification forbidden for resellers.", + "profile set modification by reseller forbidden via config"); return; } @@ -118,8 +118,8 @@ sub PUT :Allow { } if($c->user->roles eq "reseller" && !$c->config->{profile_sets}->{reseller_edit}) { - $c->log->error("profile set modification by reseller forbidden via config"); - $self->error($c, HTTP_FORBIDDEN, "Subscriber profile set modification forbidden for resellers."); + $self->error($c, HTTP_FORBIDDEN, "Subscriber profile set modification forbidden for resellers.", + "profile set modification by reseller forbidden via config"); return; } @@ -160,8 +160,8 @@ sub DELETE :Allow { } if($c->user->roles eq "reseller" && !$c->config->{profile_sets}->{reseller_edit}) { - $c->log->error("profile set deletion by reseller forbidden via config"); - $self->error($c, HTTP_FORBIDDEN, "Subscriber profile set deletion forbidden for resellers."); + $self->error($c, HTTP_FORBIDDEN, "Subscriber profile set deletion forbidden for resellers.", + "profile set deletion by reseller forbidden via config"); return; } diff --git a/lib/NGCP/Panel/Controller/API/SubscriberProfiles.pm b/lib/NGCP/Panel/Controller/API/SubscriberProfiles.pm index 81d0440eeb..c3489c1b37 100644 --- a/lib/NGCP/Panel/Controller/API/SubscriberProfiles.pm +++ b/lib/NGCP/Panel/Controller/API/SubscriberProfiles.pm @@ -111,8 +111,8 @@ sub POST :Allow { } if($c->user->roles eq "reseller" && !$c->config->{profile_sets}->{reseller_edit}) { - $c->log->error("profile creation by reseller forbidden via config"); - $self->error($c, HTTP_FORBIDDEN, "Subscriber profile creation forbidden for resellers."); + $self->error($c, HTTP_FORBIDDEN, "Subscriber profile creation forbidden for resellers.", + "profile creation by reseller forbidden via config"); return; } @@ -146,8 +146,8 @@ sub POST :Allow { } $set = $set->find($resource->{set_id}); unless($set) { - $c->log->error("subscriber profile set with id '$$resource{set_id}' does not exist"); # TODO: user, message, trace, ... - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid 'profile_set_id', does not exist"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid 'profile_set_id', does not exist", + "subscriber profile set with id '$$resource{set_id}' does not exist"); last; } @@ -156,8 +156,9 @@ sub POST :Allow { name => $resource->{name}, }); if($item) { - $c->log->error("subscriber profile with name '$$resource{name}' already exists for profile_set_id '$$resource{set_id}'"); # TODO: user, message, trace, ... - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Subscriber profile with this name already exists for this profile set"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, + "Subscriber profile with this name already exists for this profile set", + "subscriber profile with name '$$resource{name}' already exists for profile_set_id '$$resource{set_id}'"); last; } if($resource->{set_default}) { @@ -188,8 +189,7 @@ sub POST :Allow { $item->profile_attributes->create({ attribute_id => $meta->id }); } } catch($e) { - $c->log->error("failed to create subscriber profile: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create subscriber profile."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create subscriber profile.", $e); last; } diff --git a/lib/NGCP/Panel/Controller/API/SubscriberProfilesItem.pm b/lib/NGCP/Panel/Controller/API/SubscriberProfilesItem.pm index 5cafdf4888..e6057a3c10 100644 --- a/lib/NGCP/Panel/Controller/API/SubscriberProfilesItem.pm +++ b/lib/NGCP/Panel/Controller/API/SubscriberProfilesItem.pm @@ -148,8 +148,8 @@ sub DELETE :Allow { } if($c->user->roles eq "reseller" && !$c->config->{profile_sets}->{reseller_edit}) { - $c->log->error("profile deletion by reseller forbidden via config"); - $self->error($c, HTTP_FORBIDDEN, "Subscriber profile deletion forbidden for resellers."); + $self->error($c, HTTP_FORBIDDEN, "Subscriber profile deletion forbidden for resellers.", + "profile deletion by reseller forbidden via config"); return; } diff --git a/lib/NGCP/Panel/Controller/API/SubscriberRegistrations.pm b/lib/NGCP/Panel/Controller/API/SubscriberRegistrations.pm index 0cde29d021..715c1043d9 100644 --- a/lib/NGCP/Panel/Controller/API/SubscriberRegistrations.pm +++ b/lib/NGCP/Panel/Controller/API/SubscriberRegistrations.pm @@ -129,42 +129,16 @@ sub GET :Allow { return; } -sub POST :Allow { - my ($self, $c) = @_; - - { - my ($item, $resource); - - $resource = $self->get_valid_post_data( - c => $c, - media_type => 'application/json', - ); - last unless $resource; - - my $form = $self->get_form($c); - my $create = 1; +sub create_item { + my ($self, $c, $resource, $form, $process_extras) = @_; - my ($guard, $txn_ok) = ($c->model('DB')->txn_scope_guard, 0); - { - last unless $self->update_item($c, "new", undef, $resource, $form, $create); + my $item; - $guard->commit; - $txn_ok = 1; - } - last unless $txn_ok; + my $create = 1; - $item = $self->fetch_item($c, $resource, $form, $item); + return unless $self->update_item($c, "new", undef, $resource, $form, $create); - if ($item) { - $c->response->status(HTTP_CREATED); - $c->response->header(Location => sprintf('/%s%s', $c->request->path, $item->id)); - $c->response->body(q()); - } else { - $c->response->status(HTTP_CREATED); - $c->response->body(q()); - } - } - return; + return $self->fetch_item($c, $resource, $form, $item); } 1; diff --git a/lib/NGCP/Panel/Controller/API/Subscribers.pm b/lib/NGCP/Panel/Controller/API/Subscribers.pm index e67bd4defb..527626f95a 100644 --- a/lib/NGCP/Panel/Controller/API/Subscribers.pm +++ b/lib/NGCP/Panel/Controller/API/Subscribers.pm @@ -445,17 +445,17 @@ sub POST :Allow { $log_error = "failed to create subscriber, webusername-domain combination " . $c->qs($1) . " already exists"; @http_errors = ("Webusername-Domain combination '" . $1 . "' already exists.", "Webusername-Domain combination already exists."); } - $c->log->error($log_error); # TODO: user, message, trace, ... - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, $http_errors[0], $http_errors[1]); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, $http_errors[0], $http_errors[1], $log_error); last; } catch($e) { if (ref $error_info->{extended} eq 'HASH' && $error_info->{extended}->{response_code}) { - $c->log->error($error_info->{extended}->{error}); # TODO: user, message, trace, ... - $self->error($c, $error_info->{extended}->{response_code}, $error_info->{extended}->{description}); + $self->error($c, + $error_info->{extended}->{response_code}, + $error_info->{extended}->{description}, + $error_info->{extended}->{error}); last; } else { - $c->log->error("failed to create subscriber: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create subscriber: $e"); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create subscriber", $e); last; } } diff --git a/lib/NGCP/Panel/Controller/API/SystemContacts.pm b/lib/NGCP/Panel/Controller/API/SystemContacts.pm index c844c63d47..74588a18fe 100644 --- a/lib/NGCP/Panel/Controller/API/SystemContacts.pm +++ b/lib/NGCP/Panel/Controller/API/SystemContacts.pm @@ -121,8 +121,7 @@ sub POST :Allow { try { $contact = $c->model('DB')->resultset('contacts')->create($resource); } catch($e) { - $c->log->error("failed to create contact: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create contact."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create contact.", $e); last; } diff --git a/lib/NGCP/Panel/Controller/API/SystemContactsItem.pm b/lib/NGCP/Panel/Controller/API/SystemContactsItem.pm index f9a0bfafe6..20dee1df6a 100644 --- a/lib/NGCP/Panel/Controller/API/SystemContactsItem.pm +++ b/lib/NGCP/Panel/Controller/API/SystemContactsItem.pm @@ -165,8 +165,8 @@ sub DELETE :Allow { }); $contact->discard_changes(); } catch($e) { - $c->log->error("Failed to terminate contact id '".$contact->id."': $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error", + "Failed to terminate contact id '".$contact->id."'", $e); last; }; my $form = $self->get_form($c); diff --git a/lib/NGCP/Panel/Controller/API/TimeSets.pm b/lib/NGCP/Panel/Controller/API/TimeSets.pm index 78c02f01d4..139006d1a2 100644 --- a/lib/NGCP/Panel/Controller/API/TimeSets.pm +++ b/lib/NGCP/Panel/Controller/API/TimeSets.pm @@ -55,8 +55,7 @@ sub create_item { resource => $resource, ); } catch($e) { - $c->log->error("failed to create timeset: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create timeset."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create timeset.", $e); return; } diff --git a/lib/NGCP/Panel/Controller/API/TopupCash.pm b/lib/NGCP/Panel/Controller/API/TopupCash.pm index 4d12cd91ed..2d7fbec99c 100644 --- a/lib/NGCP/Panel/Controller/API/TopupCash.pm +++ b/lib/NGCP/Panel/Controller/API/TopupCash.pm @@ -58,8 +58,8 @@ sub POST :Allow { my $guard = $c->model('DB')->txn_scope_guard; { unless($c->user->billing_data) { - $c->log->error("user does not have billing data rights"); - $self->error($c, HTTP_FORBIDDEN, "Insufficient rights to create voucher"); + $self->error($c, HTTP_FORBIDDEN, "Insufficient rights to create voucher", + "user does not have billing data rights"); last; } $resource = $self->get_valid_post_data( @@ -84,9 +84,8 @@ sub POST :Allow { resource => $resource, entities => $entities, err_code => sub { - my ($err) = @_; - #$c->log->error($err); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, $err); + my ($err) = @_; + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, $err); }, ); @@ -102,8 +101,7 @@ sub POST :Allow { subscriber => $entities->{subscriber}, ); } catch($e) { - $c->log->error("failed to perform cash topup: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to perform cash topup."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to perform cash topup.", $e); last; } @@ -127,7 +125,7 @@ sub POST :Allow { is_success => $success ); } catch($e) { - $c->log->error("failed to create topup log record: $e"); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create topup log record.", $e); last; } $guard->commit; diff --git a/lib/NGCP/Panel/Controller/API/TopupVouchers.pm b/lib/NGCP/Panel/Controller/API/TopupVouchers.pm index 9cd4e8dbc5..626035a268 100644 --- a/lib/NGCP/Panel/Controller/API/TopupVouchers.pm +++ b/lib/NGCP/Panel/Controller/API/TopupVouchers.pm @@ -58,8 +58,8 @@ sub POST :Allow { my $guard = $c->model('DB')->txn_scope_guard; { unless($c->user->billing_data) { - $c->log->error("user does not have billing data rights"); - $self->error($c, HTTP_FORBIDDEN, "Insufficient rights to create voucher"); + $self->error($c, HTTP_FORBIDDEN, "Insufficient rights to create voucher", + "user does not have billing data rights"); last; } @@ -83,9 +83,8 @@ sub POST :Allow { resource => $resource, entities => $entities, err_code => sub { - my ($err) = @_; - #$c->log->error($err); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, $err); + my ($err) = @_; + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, $err); }, ); @@ -104,8 +103,7 @@ sub POST :Allow { used_at => $now, }); } catch($e) { - $c->log->error("failed to create voucher topup: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create voucher topup."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create voucher topup.", $e); last; } @@ -129,7 +127,7 @@ sub POST :Allow { is_success => $success ); } catch($e) { - $c->log->error("failed to create topup log record: $e"); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create voucher topup.", $e); last; } $guard->commit; diff --git a/lib/NGCP/Panel/Controller/API/TrustedSources.pm b/lib/NGCP/Panel/Controller/API/TrustedSources.pm index 81a1cd10e1..b93c62fb53 100644 --- a/lib/NGCP/Panel/Controller/API/TrustedSources.pm +++ b/lib/NGCP/Panel/Controller/API/TrustedSources.pm @@ -129,8 +129,8 @@ sub POST :Allow { } my $sub = $sub_rs->first; unless($sub && $sub->provisioning_voip_subscriber) { - $c->log->error("invalid subscriber_id '$$resource{subscriber_id}'"); # TODO: user, message, trace, ... - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Subscriber does not exist"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Subscriber does not exist", + "invalid subscriber_id '$$resource{subscriber_id}'"); last; } @@ -140,8 +140,7 @@ sub POST :Allow { try { $item = $c->model('DB')->resultset('voip_trusted_sources')->create($resource); } catch($e) { - $c->log->error("failed to create trusted source: " . $c->qs($e)); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create trusted source."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create trusted source.", $c->qs($e)); last; } @@ -159,8 +158,7 @@ sub POST :Allow { die "XMLRPC failed"; } } catch($e) { - $c->log->error("failed to reload kamailio: $e. Trusted source created"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to reload kamailio. Trusted source was created"); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to reload kamailio. Trusted source was created", $e); $c->response->header(Location => sprintf('/%s%d', $c->request->path, $item->id)); last; } diff --git a/lib/NGCP/Panel/Controller/API/TrustedSourcesItem.pm b/lib/NGCP/Panel/Controller/API/TrustedSourcesItem.pm index be1c4ab54a..6b01d74117 100644 --- a/lib/NGCP/Panel/Controller/API/TrustedSourcesItem.pm +++ b/lib/NGCP/Panel/Controller/API/TrustedSourcesItem.pm @@ -98,8 +98,7 @@ sub PATCH :Allow { die "XMLRPC failed"; } } catch($e) { - $c->log->error("failed to reload kamailio: $e. Trusted source modified."); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to reload kamailio. Trusted source was modified."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to reload kamailio. Trusted source was modified.", $e); last; } @@ -152,8 +151,7 @@ sub PUT :Allow { die "XMLRPC failed"; } } catch($e) { - $c->log->error("failed to reload kamailio: $e. Trusted source modified."); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to reload kamailio. Trusted source was modified."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to reload kamailio. Trusted source was modified.", $e); # TODO: do we still want to return the modified item here? last; } @@ -199,8 +197,7 @@ sub DELETE :Allow { die "XMLRPC failed"; } } catch($e) { - $c->log->error("failed to reload kamailio: $e. Trusted source deleted."); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to reload kamailio. Trusted source was deleted."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to reload kamailio. Trusted source was deleted.", $e); last; } diff --git a/lib/NGCP/Panel/Controller/API/UpnRewriteSets.pm b/lib/NGCP/Panel/Controller/API/UpnRewriteSets.pm index 4448847cd1..f179beb8a9 100644 --- a/lib/NGCP/Panel/Controller/API/UpnRewriteSets.pm +++ b/lib/NGCP/Panel/Controller/API/UpnRewriteSets.pm @@ -129,8 +129,8 @@ sub POST :Allow { my $sub = $sub_rs->first; unless($sub && $sub->provisioning_voip_subscriber) { my $debug_sid = $resource->{subscriber_id} // '(undef)'; - $c->log->error("invalid subscriber_id '$debug_sid'"); # TODO: user, message, trace, ... - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Subscriber does not exist"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Subscriber does not exist", + "invalid subscriber_id '$debug_sid'"); last; } @@ -149,8 +149,7 @@ sub POST :Allow { prov_subscriber => $sub->provisioning_voip_subscriber); $upnr_pref_rs->create({ value => $item->id }); } catch($e) { - $c->log->error("failed to create UPN rewrite set: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create UPN rewrite set."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create UPN rewrite set.", $e); last; } diff --git a/lib/NGCP/Panel/Controller/API/Vouchers.pm b/lib/NGCP/Panel/Controller/API/Vouchers.pm index 6e3e49ed00..2d6e00a3e1 100644 --- a/lib/NGCP/Panel/Controller/API/Vouchers.pm +++ b/lib/NGCP/Panel/Controller/API/Vouchers.pm @@ -111,8 +111,8 @@ sub POST :Allow { my ($self, $c) = @_; unless($c->user->billing_data) { - $c->log->error("user does not have billing data rights"); - $self->error($c, HTTP_FORBIDDEN, "Insufficient rights to create voucher"); + $self->error($c, HTTP_FORBIDDEN, "Insufficient rights to create voucher", + "user does not have billing data rights"); return; } @@ -142,8 +142,8 @@ sub POST :Allow { code => $code, }); if($item) { - $c->log->error("voucher with code '$$resource{code}' already exists for reseller_id '$$resource{reseller_id}'"); # TODO: user, message, trace, ... - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Voucher with this code already exists for this reseller"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Voucher with this code already exists for this reseller", + "voucher with code '$$resource{code}' already exists for reseller_id '$$resource{reseller_id}'"); last; } $resource->{code} = $code; @@ -153,8 +153,7 @@ sub POST :Allow { try { $item = $c->model('DB')->resultset('vouchers')->create($resource); } catch($e) { - $c->log->error("failed to create voucher: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create voucher."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create voucher.", $e); last; } diff --git a/lib/NGCP/Panel/Controller/API/VouchersItem.pm b/lib/NGCP/Panel/Controller/API/VouchersItem.pm index 8b9870cdff..abd890661a 100644 --- a/lib/NGCP/Panel/Controller/API/VouchersItem.pm +++ b/lib/NGCP/Panel/Controller/API/VouchersItem.pm @@ -58,8 +58,8 @@ sub GET :Allow { sub PATCH :Allow { my ($self, $c, $id) = @_; unless($c->user->billing_data) { - $c->log->error("user does not have billing data rights"); - $self->error($c, HTTP_FORBIDDEN, "Insufficient rights to edit voucher"); + $self->error($c, HTTP_FORBIDDEN, "Insufficient rights to edit voucher", + "user does not have billing data rights"); return; } my $guard = $c->model('DB')->txn_scope_guard; @@ -94,8 +94,8 @@ sub PATCH :Allow { sub PUT :Allow { my ($self, $c, $id) = @_; unless($c->user->billing_data) { - $c->log->error("user does not have billing data rights"); - $self->error($c, HTTP_FORBIDDEN, "Insufficient rights to edit voucher"); + $self->error($c, HTTP_FORBIDDEN, "Insufficient rights to edit voucher", + "user does not have billing data rights"); return; } my $guard = $c->model('DB')->txn_scope_guard; @@ -127,8 +127,8 @@ sub PUT :Allow { sub DELETE :Allow { my ($self, $c, $id) = @_; unless($c->user->billing_data) { - $c->log->error("user does not have billing data rights"); - $self->error($c, HTTP_FORBIDDEN, "Insufficient rights to delete voucher"); + $self->error($c, HTTP_FORBIDDEN, "Insufficient rights to delete voucher", + "user does not have billing data rights"); return; } my $guard = $c->model('DB')->txn_scope_guard; diff --git a/lib/NGCP/Panel/Role/API.pm b/lib/NGCP/Panel/Role/API.pm index c413bf1cae..c384230dda 100644 --- a/lib/NGCP/Panel/Role/API.pm +++ b/lib/NGCP/Panel/Role/API.pm @@ -348,15 +348,18 @@ sub validate_fields { } sub error { - my ($self, $c, $code, $message, $insensitive_message) = @_; + my ($self, $c, $code, $message, @errors) = @_; - my $msg = $insensitive_message // $message; - $c->log->error("error $code - $msg"); # TODO: user, trace etc + # code -> returned as HTTP code in the reply + # message -> returned as HTTP message in the reply + # errors -> contain errors for internal logging, last element often contains a DBIx exception + + $c->error(['', @errors]); $c->response->content_type('application/json'); $c->response->status($code); $c->response->body(JSON::to_json({ code => $code, message => $message })."\n"); - $c->stash(api_error_message => $message); + return; } @@ -1057,14 +1060,15 @@ sub log_response { $c->response->content_type('') if $c->response->content_type =~ qr'text/html'; # stupid RenderView getting in the way my $rc = ''; - if (@{ $c->error }) { - my $msg = join ', ', @{ $c->error }; - $rc = NGCP::Panel::Utils::Message::error( - c => $c, - type => 'api_response', - log => $msg, - ); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error"); + if ($c->has_errors) { + my $msg = join ', ', splice @{$c->error}, 1; + if ($msg) { + $rc = NGCP::Panel::Utils::Message::error( + c => $c, + type => 'api_response', + log => $msg, + ); + } $c->clear_errors; } my ($response_body, $params_data) = $self->filter_log_response( @@ -1641,8 +1645,8 @@ sub validate_request { #------ /dummy & default accessors methods -sub check_transaction_control{ - my ($self, $c, $action, $step, %params) = @_; +sub check_transaction_control { + my ($self, $c, $action, $step) = @_; my $res = 1; my $transaction_config = $self->get_config('own_transaction_control'); if (!$transaction_config) { @@ -1658,13 +1662,12 @@ sub check_transaction_control{ return $res; } -sub get_transaction_control{ - my $self = shift; - my($c, $action, $step, %params) = @_; - my $schema = $params{schema} // $c->model('DB'); - $action //= uc $c->request->method; - $step //= 'init'; - if($self->check_transaction_control($c, $action, $step, %params)){ +sub start_transaction { + my ($self, $c) = @_; + my $schema = $c->model('DB'); + my $action = uc $c->request->method; + my $step = 'start'; + if ($self->check_transaction_control($c, $action, $step)) { #todo: put it into class variables? my $til_config = $self->get_config('set_transaction_isolation'); if ($til_config) { @@ -1675,22 +1678,18 @@ sub get_transaction_control{ : 'READ COMMITTED'; $c->model('DB')->set_transaction_isolation($transaction_isolation_level); } - $c->stash->{transaction_quard} = $schema->txn_scope_guard; - return $c->stash->{transaction_quard}; + return $schema->txn_scope_guard; } return; } -sub complete_transaction{ - my $self = shift; - my($c, $action, $step, %params) = @_; - my $schema = $params{schema} // $c->model('DB'); - my $guard = $params{guard} // $c->stash->{transaction_quard}; - $action //= uc $c->request->method; - $step //= 'commit'; - if($self->check_transaction_control($c, $action, $step, %params)){ +sub commit_transaction { + my ($self, $c, $guard) = @_; + my $schema = $c->model('DB'); + my $action = uc $c->request->method; + my $step = 'commit'; + if ($self->check_transaction_control($c, $action, $step)) { $guard->commit; - $c->stash->{transaction_quard} = undef; } return; } @@ -2011,5 +2010,27 @@ sub check_wildcard_search { } +sub check_deadlock { + my ($self, $c, $error) = @_; + my $max_attempts = 2; + + return 0 unless $error; + + #my $lock_retry = $error =~ /Lock wait timeout exceeded; try restarting transaction/; + my $deadlock_retry = $error =~ /Deadlock found when trying to get lock; try restarting transaction/; + + return 0 unless $deadlock_retry; + + my $attempt = $c->stash->{deadlock_retry_attempt} //= 1; + return 0 if $attempt > $max_attempts; + NGCP::Panel::Utils::Message::info( + c => $c, + type => 'api_retry', + log => "deadlock detected, retry transaction attempt=$attempt/$max_attempts", + ); + $c->stash->{deadlock_retry_attempt} = $attempt+1; + return 1; +} + 1; # vim: set tabstop=4 expandtab: diff --git a/lib/NGCP/Panel/Role/API/Admins.pm b/lib/NGCP/Panel/Role/API/Admins.pm index 98bcca0302..db9324192c 100644 --- a/lib/NGCP/Panel/Role/API/Admins.pm +++ b/lib/NGCP/Panel/Role/API/Admins.pm @@ -131,13 +131,13 @@ sub check_duplicate{ }); } if ($existing_item && (!$item || $item->id != $existing_item->id)) { - $c->log->error("admin with login '$$resource{login}' already exists"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Admin with this login already exists"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Admin with this login already exists", + "admin with login '$$resource{login}' already exists"); return; } elsif ($existing_email && (!$item || $item->id != $existing_email->id)) { - $c->log->error("admin with email '$$resource{email}' already exists"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Admin with this email already exists"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Admin with this email already exists", + "admin with email '$$resource{email}' already exists"); return; } return 1; diff --git a/lib/NGCP/Panel/Role/API/AutoAttendants.pm b/lib/NGCP/Panel/Role/API/AutoAttendants.pm index 77c6d149c6..aee76d1e2b 100644 --- a/lib/NGCP/Panel/Role/API/AutoAttendants.pm +++ b/lib/NGCP/Panel/Role/API/AutoAttendants.pm @@ -126,8 +126,7 @@ sub update_item { }); } } catch($e) { - $c->log->error("failed to update autoattendants: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to update autoattendants."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to update autoattendants.", $e); return; }; diff --git a/lib/NGCP/Panel/Role/API/BillingNetworks.pm b/lib/NGCP/Panel/Role/API/BillingNetworks.pm index f65eec1d9b..ac61f82dcb 100644 --- a/lib/NGCP/Panel/Role/API/BillingNetworks.pm +++ b/lib/NGCP/Panel/Role/API/BillingNetworks.pm @@ -136,8 +136,7 @@ sub update_item { } $item->discard_changes; } catch($e) { - #$c->log->error("failed to create billingnetwork: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create billingnetwork."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create billingnetwork.", $e); return; }; @@ -155,7 +154,6 @@ sub prepare_blocks_resource { } return NGCP::Panel::Utils::BillingNetworks::set_blocks_from_to($resource->{blocks},sub { my ($err) = @_; - #$c->log->error($err); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, $err); }); } diff --git a/lib/NGCP/Panel/Role/API/BillingProfiles.pm b/lib/NGCP/Panel/Role/API/BillingProfiles.pm index cd82dd6cef..a5867779f2 100644 --- a/lib/NGCP/Panel/Role/API/BillingProfiles.pm +++ b/lib/NGCP/Panel/Role/API/BillingProfiles.pm @@ -183,8 +183,8 @@ sub update_profile { new_prepaid => $profile->prepaid, ); } catch($e) { - $c->log->error("Failed to update billing profile '".$profile->id."': $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error", + "Failed to update billing profile '".$profile->id."'", $e); return; }; diff --git a/lib/NGCP/Panel/Role/API/CCMapEntries.pm b/lib/NGCP/Panel/Role/API/CCMapEntries.pm index 33bf4d811d..0bd5102f3d 100644 --- a/lib/NGCP/Panel/Role/API/CCMapEntries.pm +++ b/lib/NGCP/Panel/Role/API/CCMapEntries.pm @@ -120,8 +120,7 @@ sub update_item { }); } } catch($e) { - $c->log->error("Error Updating ccmapentry for $uuid: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "CCMapEntry could not be updated."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "CCMapEntry could not be updated.", $e); return; }; diff --git a/lib/NGCP/Panel/Role/API/CFBNumberSets.pm b/lib/NGCP/Panel/Role/API/CFBNumberSets.pm index a6f2cfe9b3..cc29bb0af4 100644 --- a/lib/NGCP/Panel/Role/API/CFBNumberSets.pm +++ b/lib/NGCP/Panel/Role/API/CFBNumberSets.pm @@ -176,8 +176,7 @@ sub update_item { return $self->hal_from_item($c, $item); }); } catch($e) { - $c->log->error("failed to create cfbnumberset: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create cfbnumberset."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create cfbnumberset.", $e); return; }; diff --git a/lib/NGCP/Panel/Role/API/CFDestinationSets.pm b/lib/NGCP/Panel/Role/API/CFDestinationSets.pm index cb178f0463..1ed81fdb8f 100644 --- a/lib/NGCP/Panel/Role/API/CFDestinationSets.pm +++ b/lib/NGCP/Panel/Role/API/CFDestinationSets.pm @@ -215,8 +215,7 @@ sub update_item { ); } } catch($e) { - $c->log->error("failed to create cfdestinationset: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create cfdestinationset."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create cfdestinationset.", $e); return; }; diff --git a/lib/NGCP/Panel/Role/API/CFSourceSets.pm b/lib/NGCP/Panel/Role/API/CFSourceSets.pm index 82d07f288f..d85e2d4e62 100644 --- a/lib/NGCP/Panel/Role/API/CFSourceSets.pm +++ b/lib/NGCP/Panel/Role/API/CFSourceSets.pm @@ -186,8 +186,7 @@ sub update_item { } $item->discard_changes; } catch($e) { - $c->log->error("failed to create cfsourceset: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create cfsourceset."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create cfsourceset.", $e); return; }; @@ -258,8 +257,8 @@ sub check_duplicate { subscriber_id => $subscriber->id })->first; if ($existing_item && (!$item || $item->id != $existing_item->id)) { - $c->log->error("source_set name '$$resource{name}' already exists"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "A Sourceset with this name already exists"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "A Sourceset with this name already exists", + "source_set name '$$resource{name}' already exists"); return; } return 1; diff --git a/lib/NGCP/Panel/Role/API/CFTimeSets.pm b/lib/NGCP/Panel/Role/API/CFTimeSets.pm index a55190752e..08009451e2 100644 --- a/lib/NGCP/Panel/Role/API/CFTimeSets.pm +++ b/lib/NGCP/Panel/Role/API/CFTimeSets.pm @@ -452,8 +452,7 @@ sub update_item { $item->create_related("voip_cf_periods", $t); } } catch($e) { - $c->log->error("failed to create cftimeset: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create cftimeset."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create cftimeset.", $e); return; }; diff --git a/lib/NGCP/Panel/Role/API/CallForwards.pm b/lib/NGCP/Panel/Role/API/CallForwards.pm index 1cf5adab7a..f02c9e5cf2 100644 --- a/lib/NGCP/Panel/Role/API/CallForwards.pm +++ b/lib/NGCP/Panel/Role/API/CallForwards.pm @@ -119,6 +119,17 @@ sub item_by_id { return $self->item_rs($c)->search_rs({'me.id' => $id})->first; } +sub resource_from_item { + my($self, $c, $item) = @_; + + return $self->hal_from_item($c, $item)->resource; +} + +sub get_journal_item_hal { + my ($self, $c, $item, $params) = @_; + return ($self->hal_from_item($c, $item), $item->id); +} + sub update_item { my ($self, $c, $item, $old_resource, $resource, $form) = @_; @@ -145,17 +156,14 @@ sub update_item { next unless ($allowed_prefs->{$type}); for my $d (@{ $resource->{$type}{destinations} }) { if (exists $d->{timeout} && ! is_int($d->{timeout})) { - $c->log->error("Invalid timeout in '$type'"); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid timeout in '$type'"); return; } if (defined $d->{announcement_id}) { if('customhours' ne $d->{destination}){ - $c->log->error("Invalid parameter 'announcement_id' for the destination '".$c->qs($d->{destination})."' in '$type'"); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid parameter 'announcement_id' for the destination '".$c->qs($d->{destination})."' in '$type'"); return; }elsif(! is_int($d->{announcement_id})){ - $c->log->error("Invalid announcement_id in '$type'"); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid announcement_id in '$type'"); return; }elsif(! $c->model('DB')->resultset('voip_sound_handles')->search_rs({ @@ -165,7 +173,6 @@ sub update_item { 'join' => 'group' } )->first() ){ - $c->log->error("Unknown announcement_id in '$type'"); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Unknown announcement_id in '$type'"); return; } @@ -380,8 +387,7 @@ sub update_item { } } catch($e) { - $c->log->error("Error Updating '$type': $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "CallForward '$type' could not be updated."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "CallForward '$type' could not be updated.", $e); return; } } diff --git a/lib/NGCP/Panel/Role/API/CallQueues.pm b/lib/NGCP/Panel/Role/API/CallQueues.pm index 98ae766a5d..73725a6595 100644 --- a/lib/NGCP/Panel/Role/API/CallQueues.pm +++ b/lib/NGCP/Panel/Role/API/CallQueues.pm @@ -20,7 +20,7 @@ sub _get_redis { if (defined $select) { $stash_key .= '_' . $select; } else { - $c->log->error("redis store not specified"); + $c->error("redis store not specified"); return; } my $redis = $c->stash->{$stash_key}; @@ -32,13 +32,13 @@ sub _get_redis { cnx_timeout => 3, ); unless ($redis) { - $c->log->error("Failed to connect to central redis url " . $c->config->{redis}->{central_url}); + $c->error("Failed to connect to central redis url " . $c->config->{redis}->{central_url}); return; } $redis->select($select) if defined $select; $c->stash($stash_key => $redis); } catch($e) { - $c->log->error("Failed to fetch callqueue information from redis: $e"); + $c->error("Failed to fetch callqueue information from redis: $e"); return; } } diff --git a/lib/NGCP/Panel/Role/API/Contracts.pm b/lib/NGCP/Panel/Role/API/Contracts.pm index 04514f7c18..f043492b96 100644 --- a/lib/NGCP/Panel/Role/API/Contracts.pm +++ b/lib/NGCP/Panel/Role/API/Contracts.pm @@ -152,7 +152,6 @@ sub update_contract { now => $now, err_code => sub { my ($err) = @_; - #$c->log->error($err); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, $err); }); delete $resource->{type}; @@ -230,11 +229,9 @@ sub update_contract { return $contract; # TODO: what about changed product, do we allow it? } catch($e) { - $c->log->error("Failed to update contract id '".$contract->id."': $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error", + "Failed to update contract id '".$contract->id."'", $e); }; - - } 1; diff --git a/lib/NGCP/Panel/Role/API/CustomerFraudEvents.pm b/lib/NGCP/Panel/Role/API/CustomerFraudEvents.pm index 1051a137a2..2b007725e0 100644 --- a/lib/NGCP/Panel/Role/API/CustomerFraudEvents.pm +++ b/lib/NGCP/Panel/Role/API/CustomerFraudEvents.pm @@ -204,8 +204,7 @@ sub update_item { map { $_ => $resource->{$_} } qw(notify_status notified_at) })->discard_changes; } catch($e) { - $c->log->error("failed to update customer fraud event: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to update customer fraud event."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to update customer fraud event.", $e); return; }; diff --git a/lib/NGCP/Panel/Role/API/CustomerFraudPreferences.pm b/lib/NGCP/Panel/Role/API/CustomerFraudPreferences.pm index c744310304..1606323397 100644 --- a/lib/NGCP/Panel/Role/API/CustomerFraudPreferences.pm +++ b/lib/NGCP/Panel/Role/API/CustomerFraudPreferences.pm @@ -165,7 +165,7 @@ sub update_item { }); $customer = $item->contract; } catch($e) { - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to set customer fraud preference: $e"); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to set customer fraud preference", $e); return; }; diff --git a/lib/NGCP/Panel/Role/API/CustomerLocations.pm b/lib/NGCP/Panel/Role/API/CustomerLocations.pm index 6b14fb43cd..40f086b623 100644 --- a/lib/NGCP/Panel/Role/API/CustomerLocations.pm +++ b/lib/NGCP/Panel/Role/API/CustomerLocations.pm @@ -116,7 +116,7 @@ sub update_item { } $item->discard_changes; } catch($e) { - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create customer location."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create customer location.", $e); return; }; diff --git a/lib/NGCP/Panel/Role/API/CustomerPhonebookEntries.pm b/lib/NGCP/Panel/Role/API/CustomerPhonebookEntries.pm index 3ba7adb434..41ef398927 100644 --- a/lib/NGCP/Panel/Role/API/CustomerPhonebookEntries.pm +++ b/lib/NGCP/Panel/Role/API/CustomerPhonebookEntries.pm @@ -73,14 +73,12 @@ sub check_resource { } unless ($check_rs->first) { - $c->log->error("Invalid 'customer_id'"); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid 'customer_id'"); return; } } unless ($resource->{contract_id}) { - $c->log->error("Required 'customer_id'"); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Required 'customer_id'"); return; } @@ -92,7 +90,6 @@ sub check_resource { })->first; if ($exists) { - $c->log->error("Duplicate entry 'customer_id-number"); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Duplicate entry 'customer_id-number"); return; } diff --git a/lib/NGCP/Panel/Role/API/Customers.pm b/lib/NGCP/Panel/Role/API/Customers.pm index 8cb1f58e75..1a7c0d3e0a 100644 --- a/lib/NGCP/Panel/Role/API/Customers.pm +++ b/lib/NGCP/Panel/Role/API/Customers.pm @@ -176,7 +176,6 @@ sub update_customer { delete_mappings => \$delete_mappings, err_code => sub { my ($err) = @_; - #$c->log->error($err); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, $err); }); delete $resource->{type}; @@ -277,8 +276,8 @@ sub update_customer { return $customer; # TODO: what about changed product, do we allow it? } catch($e) { - $c->log->error("Failed to update customer contract id '".$customer->id."': $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error", + "Failed to update customer contract id '".$customer->id."'", $e); }; } diff --git a/lib/NGCP/Panel/Role/API/EmailTemplates.pm b/lib/NGCP/Panel/Role/API/EmailTemplates.pm index b0cb6bddd7..c9f45d033f 100644 --- a/lib/NGCP/Panel/Role/API/EmailTemplates.pm +++ b/lib/NGCP/Panel/Role/API/EmailTemplates.pm @@ -96,8 +96,8 @@ sub update_item { name => $resource->{name}, }); if($dup_item && $dup_item->id != $item->id) { - $c->log->error("email template with name '$$resource{name}' already exists for reseller_id '$$resource{reseller_id}'"); # TODO: user, message, trace, ... - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Email template with this name already exists for this reseller"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Email template with this name already exists for this reseller", + "email template with name '$$resource{name}' already exists for reseller_id '$$resource{reseller_id}'"); return; } diff --git a/lib/NGCP/Panel/Role/API/EmergencyMappingContainers.pm b/lib/NGCP/Panel/Role/API/EmergencyMappingContainers.pm index 2bdaaf0836..330db5e54a 100644 --- a/lib/NGCP/Panel/Role/API/EmergencyMappingContainers.pm +++ b/lib/NGCP/Panel/Role/API/EmergencyMappingContainers.pm @@ -90,8 +90,8 @@ sub update_item { my $reseller_item = $c->model('DB')->resultset('resellers')->find($resource->{reseller_id}); unless($reseller_item) { - $c->log->error("reseller id '$$resource{reseller_id}' does not exist"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Reseller id does not exist"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Reseller id does not exist", + "reseller id '$$resource{reseller_id}' does not exist"); return; } @@ -100,8 +100,8 @@ sub update_item { name => $resource->{name}, }); if($dup_item && $dup_item->id != $item->id) { - $c->log->error("emergency mapping container with name '$$resource{name}' already exists for this reseller"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Emergency mapping container with this name already exists for this reseller"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Emergency mapping container with this name already exists for this reseller", + "emergency mapping container with name '$$resource{name}' already exists for this reseller"); return; } diff --git a/lib/NGCP/Panel/Role/API/EmergencyMappings.pm b/lib/NGCP/Panel/Role/API/EmergencyMappings.pm index 9b700983fa..56b0aff8fa 100644 --- a/lib/NGCP/Panel/Role/API/EmergencyMappings.pm +++ b/lib/NGCP/Panel/Role/API/EmergencyMappings.pm @@ -91,16 +91,16 @@ sub update_item { my $container = $c->model('DB')->resultset('emergency_containers')->find($resource->{emergency_container_id}); unless($container) { - $c->log->error("invalid emergency container id '$$resource{emergency_container_id}'"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Emergency container id does not exist"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Emergency container id does not exist", + "invalid emergency container id '$$resource{emergency_container_id}'"); return; } if ($old_resource->{code} ne $resource->{code} && $c->model('DB')->resultset('emergency_mappings')->search({ emergency_container_id => $container->id, code => $resource->{code} },undef)->count > 0) { - $c->log->error("Emergency mapping code '$$resource{code}' already exists for container id '$$resource{emergency_container_id}'"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "emergency mapping code already exists for emergency container"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "emergency mapping code already exists for emergency container", + "Emergency mapping code '$$resource{code}' already exists for container id '$$resource{emergency_container_id}'"); return; } diff --git a/lib/NGCP/Panel/Role/API/FaxserverSettings.pm b/lib/NGCP/Panel/Role/API/FaxserverSettings.pm index 23fe67c3dc..15d7f14a3e 100644 --- a/lib/NGCP/Panel/Role/API/FaxserverSettings.pm +++ b/lib/NGCP/Panel/Role/API/FaxserverSettings.pm @@ -55,8 +55,8 @@ sub resource_from_item{ my $billing_subscriber = NGCP::Panel::Utils::API::Subscribers::get_active_subscriber($self, $c, $item->id); unless($billing_subscriber) { - $c->log->error("invalid subscriber id $item->id for fax send"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Fax subscriber not found."); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Fax subscriber not found.", + "invalid subscriber id $item->id for fax send"); return; } my $prov_subs = $item->provisioning_voip_subscriber; @@ -68,7 +68,8 @@ sub resource_from_item{ $fax_preference = $prov_subs->create_related('voip_fax_preference', {}); $fax_preference->discard_changes; # reload } catch($e) { - $c->log->error("Error creating empty fax_preference on get"); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error", + "Error creating empty fax_preference on get", $e); }; } diff --git a/lib/NGCP/Panel/Role/API/Interceptions.pm b/lib/NGCP/Panel/Role/API/Interceptions.pm index ff1c23d2ed..b0226ee044 100644 --- a/lib/NGCP/Panel/Role/API/Interceptions.pm +++ b/lib/NGCP/Panel/Role/API/Interceptions.pm @@ -128,8 +128,7 @@ sub update_item { my ($sub, $reseller, $voip_number) = NGCP::Panel::Utils::Interception::subresnum_from_number($c, $resource->{number}, sub { my ($msg,$field,$response) = @_; - $c->log->error($msg); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, $response); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, $response, $msg); return 0; }); return unless($sub && $reseller); @@ -139,17 +138,15 @@ sub update_item { $resource->{sip_domain} = $sub->domain->domain; if($resource->{liid} && ($old_resource->{liid} ne $resource->{liid})) { - $c->log->error("Attempt to change liid: ".$old_resource->{liid}." => ".$resource->{liid}.";"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "liid can not be changed"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "liid can not be changed", + "Attempt to change liid: ".$old_resource->{liid}." => ".$resource->{liid}.";"); return; } if($resource->{x3_required} && (!defined $resource->{x3_host} || !defined $resource->{x3_port})) { - $c->log->error("Missing parameter 'x3_host' or 'x3_port' with 'x3_required' activated"); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Missing parameter 'x3_host' or 'x3_port' with 'x3_required' activated"); return; } if (defined $resource->{x3_port} && !is_int($resource->{x3_port})) { - $c->log->error("Parameter 'x3_port' should be an integer"); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Parameter 'x3_port' should be an integer"); last; } @@ -174,7 +171,6 @@ sub update_item { cc_delivery_port => $resource->{cc_delivery_port}, }); unless($res) { - $c->log->error("failed to update capture agents"); $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to update capture agents"); last; } diff --git a/lib/NGCP/Panel/Role/API/InvoiceTemplates.pm b/lib/NGCP/Panel/Role/API/InvoiceTemplates.pm index 786fdb341a..8dd8ad944d 100644 --- a/lib/NGCP/Panel/Role/API/InvoiceTemplates.pm +++ b/lib/NGCP/Panel/Role/API/InvoiceTemplates.pm @@ -96,8 +96,8 @@ sub update_item { name => $resource->{name}, }); if($dup_item && $dup_item->id != $item->id) { - $c->log->error("invoice template with name '$$resource{name}' already exists for reseller_id '$$resource{reseller_id}'"); # TODO: user, message, trace, ... - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invoice template with this name already exists for this reseller"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invoice template with this name already exists for this reseller", + "invoice template with name '$$resource{name}' already exists for reseller_id '$$resource{reseller_id}'"); return; } diff --git a/lib/NGCP/Panel/Role/API/LnpCarriers.pm b/lib/NGCP/Panel/Role/API/LnpCarriers.pm index 07151a96f2..5539ac8661 100644 --- a/lib/NGCP/Panel/Role/API/LnpCarriers.pm +++ b/lib/NGCP/Panel/Role/API/LnpCarriers.pm @@ -79,8 +79,8 @@ sub update_item { name => $resource->{name}, }); if($dup_item && $dup_item->id != $item->id) { - $c->log->error("lnp carrier with name '$$resource{name}' already exists"); # TODO: user, message, trace, ... - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "LNP carrier with this name already exists"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "LNP carrier with this name already exists", + "lnp carrier with name '$$resource{name}' already exists"); return; } diff --git a/lib/NGCP/Panel/Role/API/LnpNumbers.pm b/lib/NGCP/Panel/Role/API/LnpNumbers.pm index aad8fac662..10baee4d9c 100644 --- a/lib/NGCP/Panel/Role/API/LnpNumbers.pm +++ b/lib/NGCP/Panel/Role/API/LnpNumbers.pm @@ -87,8 +87,8 @@ sub update_item { my $carrier = $c->model('DB')->resultset('lnp_providers')->find($resource->{lnp_provider_id}); unless($carrier) { - $c->log->error("invalid carrier_id '$$resource{lnp_provider_id}'"); # TODO: user, message, trace, ... - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "LNP carrier_id does not exist"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "LNP carrier_id does not exist", + "invalid carrier_id '$$resource{lnp_provider_id}'"); return; } diff --git a/lib/NGCP/Panel/Role/API/MailToFaxSettings.pm b/lib/NGCP/Panel/Role/API/MailToFaxSettings.pm index 5e3001feda..7f3281ee0d 100644 --- a/lib/NGCP/Panel/Role/API/MailToFaxSettings.pm +++ b/lib/NGCP/Panel/Role/API/MailToFaxSettings.pm @@ -35,7 +35,7 @@ sub hal_from_item { $mtf_preference = $prov_subs->create_related('voip_mail_to_fax_preference', {}); $mtf_preference->discard_changes; # reload } catch($e) { - $c->log->error("Error creating empty mail_to_fax_preference on get"); + $c->error('Error creating empty mail_to_fax_preference on get'); }; } @@ -198,8 +198,7 @@ sub update_item { $acl_rs->create($acl); } } catch($e) { - $c->log->error("Error Updating mailtofaxsettings: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "mailtofaxsettings could not be updated."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "mailtofaxsettings could not be updated.", $e); return; }; diff --git a/lib/NGCP/Panel/Role/API/ManagerSecretary.pm b/lib/NGCP/Panel/Role/API/ManagerSecretary.pm index 64f1112089..d703e215aa 100644 --- a/lib/NGCP/Panel/Role/API/ManagerSecretary.pm +++ b/lib/NGCP/Panel/Role/API/ManagerSecretary.pm @@ -266,8 +266,7 @@ sub update_item { $dset->discard_changes if $dset; # update destinations } catch($e) { - $c->log->error("Error Updating '$cf_type': $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "CallForward '$cf_type' could not be updated."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "CallForward '$cf_type' could not be updated.", $e); return; } diff --git a/lib/NGCP/Panel/Role/API/NcosLevels.pm b/lib/NGCP/Panel/Role/API/NcosLevels.pm index 1fc9d61ce9..5161273695 100644 --- a/lib/NGCP/Panel/Role/API/NcosLevels.pm +++ b/lib/NGCP/Panel/Role/API/NcosLevels.pm @@ -104,7 +104,6 @@ sub update_item { }); if (!$time_set) { my $err = "Time set with id '$resource->{time_set_id}' does not exist or does not belong to this reseller"; - $c->log->error($err); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, $err); return; } @@ -115,8 +114,8 @@ sub update_item { level => $resource->{level}, }); if($dup_item && $dup_item->id != $item->id) { - $c->log->error("ncos level '$$resource{level}' already exists for reseller_id '$$resource{reseller_id}'"); # TODO: user, message, trace, ... - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "NCOS level already exists for this reseller"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "NCOS level already exists for this reseller", + "ncos level '$$resource{level}' already exists for reseller_id '$$resource{reseller_id}'"); return; } diff --git a/lib/NGCP/Panel/Role/API/NcosLnpCarriers.pm b/lib/NGCP/Panel/Role/API/NcosLnpCarriers.pm index bd01a2be3e..a9f98c66e8 100644 --- a/lib/NGCP/Panel/Role/API/NcosLnpCarriers.pm +++ b/lib/NGCP/Panel/Role/API/NcosLnpCarriers.pm @@ -89,8 +89,8 @@ sub update_item { $resource->{ncos_level_id}, ); unless($level) { - $c->log->error("invalid ncos_level_id '$$resource{ncos_level_id}'"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid ncos_level_id, level does not exist"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid ncos_level_id, level does not exist", + "invalid ncos_level_id '$$resource{ncos_level_id}'"); return; } @@ -98,8 +98,8 @@ sub update_item { lnp_provider_id => $resource->{lnp_provider_id}, })->first; if($dup_item && $dup_item->id != $item->id) { - $c->log->error("ncos lnp carrier '$$resource{lnp_provider_id}' already exists for ncos_level_id '$$resource{ncos_level_id}'"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "NCOS lnp entry already exists for given ncos level"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "NCOS lnp entry already exists for given ncos level", + "ncos lnp carrier '$$resource{lnp_provider_id}' already exists for ncos_level_id '$$resource{ncos_level_id}'"); return; } diff --git a/lib/NGCP/Panel/Role/API/NcosLnpPatterns.pm b/lib/NGCP/Panel/Role/API/NcosLnpPatterns.pm index f55f9a69e0..a7fac94518 100644 --- a/lib/NGCP/Panel/Role/API/NcosLnpPatterns.pm +++ b/lib/NGCP/Panel/Role/API/NcosLnpPatterns.pm @@ -86,8 +86,8 @@ sub update_item { }); my $lnp_list = $lnp_list_rs->first; unless($lnp_list) { - $c->log->error("invalid ncos_lnp_list_id '$$resource{ncos_lnp_list_id}'"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid ncos_lnp_list_id, lnp list does not exist"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid ncos_lnp_list_id, lnp list does not exist", + "invalid ncos_lnp_list_id '$$resource{ncos_lnp_list_id}'"); return; } @@ -95,8 +95,8 @@ sub update_item { pattern => $resource->{pattern}, })->first; if($dup_item && $dup_item->id != $item->id) { - $c->log->error("ncos pattern '$$resource{pattern}' already exists for ncos_lnp_list_id '$$resource{ncos_lnp_list_id}'"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "NCOS pattern already exists for given ncos lnp list id"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "NCOS pattern already exists for given ncos lnp list id", + "ncos pattern '$$resource{pattern}' already exists for ncos_lnp_list_id '$$resource{ncos_lnp_list_id}'"); return; } diff --git a/lib/NGCP/Panel/Role/API/NcosPatterns.pm b/lib/NGCP/Panel/Role/API/NcosPatterns.pm index 1429fff7c7..e7c5555e7c 100644 --- a/lib/NGCP/Panel/Role/API/NcosPatterns.pm +++ b/lib/NGCP/Panel/Role/API/NcosPatterns.pm @@ -92,8 +92,9 @@ sub update_item { } my $level = $level_rs->first; unless($level) { - $c->log->error("invalid ncos_level_id '$$resource{ncos_level_id}' for reseller_id '$$resource{reseller_id}'"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid ncos_level_id, level does not exist"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, + "Invalid ncos_level_id, level does not exist", + "invalid ncos_level_id '$$resource{ncos_level_id}' for reseller_id '$$resource{reseller_id}'"); return; } @@ -101,8 +102,8 @@ sub update_item { pattern => $resource->{pattern}, })->first; if($dup_item && $dup_item->id != $item->id) { - $c->log->error("ncos pattern '$$resource{pattern}' already exists for ncos_level_id '$$resource{ncos_level_id}'"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "NCOS pattern already exists for given ncos level"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "NCOS pattern already exists for given ncos level", + "ncos pattern '$$resource{pattern}' already exists for ncos_level_id '$$resource{ncos_level_id}'"); return; } diff --git a/lib/NGCP/Panel/Role/API/PbxDeviceConfigs.pm b/lib/NGCP/Panel/Role/API/PbxDeviceConfigs.pm index 38b6f47508..a1596505d1 100644 --- a/lib/NGCP/Panel/Role/API/PbxDeviceConfigs.pm +++ b/lib/NGCP/Panel/Role/API/PbxDeviceConfigs.pm @@ -109,8 +109,8 @@ sub update_item { } my $model = $model_rs->first; unless($model) { - $c->log->error("invalid device_id '$$resource{device_id}'"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Pbx device model does not exist"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Pbx device model does not exist", + "invalid device_id '$$resource{device_id}'"); last; } diff --git a/lib/NGCP/Panel/Role/API/PbxDeviceFirmwares.pm b/lib/NGCP/Panel/Role/API/PbxDeviceFirmwares.pm index 2bff283137..f84766449f 100644 --- a/lib/NGCP/Panel/Role/API/PbxDeviceFirmwares.pm +++ b/lib/NGCP/Panel/Role/API/PbxDeviceFirmwares.pm @@ -104,8 +104,8 @@ sub update_item { } my $model = $model_rs->first; unless($model) { - $c->log->error("invalid device_id '$$resource{device_id}'"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Pbx device model does not exist"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Pbx device model does not exist", + "invalid device_id '$$resource{device_id}'"); return; } diff --git a/lib/NGCP/Panel/Role/API/PbxDeviceModels.pm b/lib/NGCP/Panel/Role/API/PbxDeviceModels.pm index 58746fcc5c..d7f7491457 100644 --- a/lib/NGCP/Panel/Role/API/PbxDeviceModels.pm +++ b/lib/NGCP/Panel/Role/API/PbxDeviceModels.pm @@ -163,41 +163,41 @@ sub check_resource{ my $reseller = $c->model('DB')->resultset('resellers')->find($resource->{reseller_id}); unless($reseller) { - $c->log->error("invalid reseller_id '".((defined $resource->{reseller_id})?$resource->{reseller_id} : "undefined")."', does not exist"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid reseller_id, does not exist"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid reseller_id, does not exist", + "invalid reseller_id '".((defined $resource->{reseller_id})?$resource->{reseller_id} : "undefined")."', does not exist"); return; } my $linerange = $resource->{linerange}; unless(ref $linerange eq "ARRAY") { - $c->log->error("linerange must be array"); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid linerange parameter, must be array"); return; } foreach my $range(@{ $linerange }) { unless(ref $range eq "HASH") { - $c->log->error("all elements in linerange must be hashes, but this is " . ref $range . ": " . Dumper $range); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid range definition inside linerange parameter, all must be hash"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid range definition inside linerange parameter, all must be hash", + "all elements in linerange must be hashes, but this is " . ref $range . ": " . Dumper $range); return; } foreach my $elem(qw/can_private can_shared can_blf can_speeddial can_forward can_transfer keys/) { unless(exists $range->{$elem}) { - $c->log->error("missing mandatory attribute '$elem' in a linerange element"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid range definition inside linerange parameter, missing attribute '$elem'"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, + "Invalid range definition inside linerange parameter, missing attribute '$elem'", + "missing mandatory attribute '$elem' in a linerange element"); return; } } unless(ref $range->{keys} eq "ARRAY") { - $c->log->error("linerange.keys must be array"); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid linerange.keys parameter, must be array"); #last? not next? return; } foreach my $label(@{ $range->{keys} }) { unless(ref $label eq "HASH") { - $c->log->error("all elements in linerange must be hashes, but this is " . ref $range . ": " . Dumper $range); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid range definition inside linerange parameter, all must be hash"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, + "Invalid range definition inside linerange parameter, all must be hash", + "all elements in linerange must be hashes, but this is " . ref $range . ": " . Dumper $range); return; } } @@ -215,8 +215,8 @@ sub check_duplicate{ model => $resource->{model}, }); if($existing_item && (!$item || $item->id != $existing_item->id)) { - $c->log->error("device model with vendor '$$resource{vendor}' and model '$$resource{model}'already exists for reseller_id '$$resource{reseller_id}'"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Device model already exists for this reseller"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Device model already exists for this reseller", + "device model with vendor '$$resource{vendor}' and model '$$resource{model}'already exists for reseller_id '$$resource{reseller_id}'"); return; } return 1; diff --git a/lib/NGCP/Panel/Role/API/PbxDeviceProfiles.pm b/lib/NGCP/Panel/Role/API/PbxDeviceProfiles.pm index bfc916e606..1e118efe76 100644 --- a/lib/NGCP/Panel/Role/API/PbxDeviceProfiles.pm +++ b/lib/NGCP/Panel/Role/API/PbxDeviceProfiles.pm @@ -99,8 +99,8 @@ sub update_item { name => $resource->{name}, }); if($dup_item && $dup_item->id != $item->id) { - $c->log->error("Pbx device profile with name '$$resource{name}' already exists for config_id '$$resource{config_id}'"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Pbx device profile with this name already exists for this config"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Pbx device profile with this name already exists for this config", + "Pbx device profile with name '$$resource{name}' already exists for config_id '$$resource{config_id}'"); last; } my $config_rs = $c->model('DB')->resultset('autoprov_configs')->search({ @@ -116,8 +116,8 @@ sub update_item { } my $config = $config_rs->first; unless($config) { - $c->log->error("Pbx device config with confg_id '$$resource{config_id}' does not exist"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Pbx device config does not exist"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Pbx device config does not exist", + "Pbx device config with confg_id '$$resource{config_id}' does not exist"); last; } diff --git a/lib/NGCP/Panel/Role/API/PbxDevices.pm b/lib/NGCP/Panel/Role/API/PbxDevices.pm index db104e9ab0..e4c71436b4 100644 --- a/lib/NGCP/Panel/Role/API/PbxDevices.pm +++ b/lib/NGCP/Panel/Role/API/PbxDevices.pm @@ -260,19 +260,22 @@ sub model_from_profile_id { } my $profile = $profile_rs->first; unless($profile) { - $c->log->error("failed to find device profile with id 'profile_id'"); $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Invalid profile_id, device profile does not exist."); return; } my $config = $profile->config; unless($config) { - $c->log->error("device profile with id '" . $profile->id . "' doesn't have a config"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Invalid profile_id, device profile does not have a config."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, + "Invalid profile_id, device profile does not have a config.", + "device profile with id '" . $profile->id . "' doesn't have a config", + ); return; } unless($config->device) { - $c->log->error("device config id '" . $config->id . "' doesn't have a device model"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Invalid profile_id, device profile config does not have a device model."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, + "Invalid profile_id, device profile config does not have a device model.", + "device config id '" . $config->id . "' doesn't have a device model", + ); return; } diff --git a/lib/NGCP/Panel/Role/API/PeeringGroups.pm b/lib/NGCP/Panel/Role/API/PeeringGroups.pm index 28c860635c..8a6d943bfa 100644 --- a/lib/NGCP/Panel/Role/API/PeeringGroups.pm +++ b/lib/NGCP/Panel/Role/API/PeeringGroups.pm @@ -104,8 +104,7 @@ sub update_item { name => $resource->{name}, }); if($dup_item && $dup_item->id != $item->id) { - $c->log->error("peering group with name '$$resource{name}' already exists"); # TODO: user, message, trace, ... - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "peering group with this name already exists"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "peering group with this name already exists", $resource->{name}); return; } diff --git a/lib/NGCP/Panel/Role/API/PeeringInboundRules.pm b/lib/NGCP/Panel/Role/API/PeeringInboundRules.pm index ca75402ec6..37884945d0 100644 --- a/lib/NGCP/Panel/Role/API/PeeringInboundRules.pm +++ b/lib/NGCP/Panel/Role/API/PeeringInboundRules.pm @@ -75,7 +75,6 @@ sub update_item { resource => $resource, ); unless($c->model('DB')->resultset('voip_peer_groups')->find($resource->{group_id})) { - $c->log->error("peering group $$resource{group_id} does not exist"); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "peering group $$resource{group_id} does not exist"); return; } @@ -89,7 +88,6 @@ sub update_item { priority => $resource->{priority}, }); if($dup_item && $dup_item->id != $item->id) { - $c->log->error("peering rule already exists"); # TODO: user, message, trace, ... $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "peering rule already exists"); return; } @@ -100,7 +98,6 @@ sub update_item { }, {} )->count) { - $c->log->error("peering rule priority $$resource{priority} already exists for this group"); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "peering rule priority $$resource{priority} already exists for this group"); return; } diff --git a/lib/NGCP/Panel/Role/API/PeeringRules.pm b/lib/NGCP/Panel/Role/API/PeeringRules.pm index fbd0490aa8..cecee94cd1 100644 --- a/lib/NGCP/Panel/Role/API/PeeringRules.pm +++ b/lib/NGCP/Panel/Role/API/PeeringRules.pm @@ -81,7 +81,6 @@ sub update_item { callee_prefix => $resource->{callee_prefix}, }); if($dup_item && $dup_item->id != $item->id) { - $c->log->error("peering rule already exists"); # TODO: user, message, trace, ... $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "peering rule already exists"); return; } diff --git a/lib/NGCP/Panel/Role/API/PeeringServers.pm b/lib/NGCP/Panel/Role/API/PeeringServers.pm index 2db3ecb67a..f632052e63 100644 --- a/lib/NGCP/Panel/Role/API/PeeringServers.pm +++ b/lib/NGCP/Panel/Role/API/PeeringServers.pm @@ -79,8 +79,8 @@ sub update_item { name => $resource->{name}, }); if($dup_item && $dup_item->id != $item->id) { - $c->log->error("peering server with name '$$resource{name}' already exists"); # TODO: user, message, trace, ... - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "peering server with this name already exists"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "peering server with this name already exists", + "peering server with name '$$resource{name}' already exists"); return; } diff --git a/lib/NGCP/Panel/Role/API/ProfilePackages.pm b/lib/NGCP/Panel/Role/API/ProfilePackages.pm index 4526581bed..386f0975d7 100644 --- a/lib/NGCP/Panel/Role/API/ProfilePackages.pm +++ b/lib/NGCP/Panel/Role/API/ProfilePackages.pm @@ -153,7 +153,6 @@ sub update_item { mappings_to_create => $mappings_to_create, err_code => sub { my ($err) = @_; - #$c->log->error($err); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, $err); }); @@ -165,8 +164,7 @@ sub update_item { } $item->discard_changes; } catch($e) { - $c->log->error("failed to create profilepackage: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create profilepackage."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create profilepackage.", $e); return; }; diff --git a/lib/NGCP/Panel/Role/API/Reminders.pm b/lib/NGCP/Panel/Role/API/Reminders.pm index aa2cf6fa7a..17b4503100 100644 --- a/lib/NGCP/Panel/Role/API/Reminders.pm +++ b/lib/NGCP/Panel/Role/API/Reminders.pm @@ -126,8 +126,8 @@ sub update_item { pref_list => ['reminder'], ); unless ($allowed_prefs->{reminder}) { - $c->log->error("Not permitted to edit reminder via subscriber profile"); - $self->error($c, HTTP_FORBIDDEN, "Not permitted to edit reminder"); + $self->error($c, HTTP_FORBIDDEN, "Not permitted to edit reminder", + "Not permitted to edit reminder via subscriber profile"); return; } @@ -138,8 +138,8 @@ sub update_item { id => { '!=' => $item->id }, })->count; if($dup) { - $c->log->error("already existing reminder for subscriber_id '$$resource{subscriber_id}'"); # TODO: user, message, trace, ... - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Subscriber already has a reminder"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Subscriber already has a reminder", + "already existing reminder for subscriber_id '$$resource{subscriber_id}'"); return; } @@ -174,8 +174,8 @@ sub get_subscriber_by_id { } my $sub = $sub_rs->first; unless ($sub && $sub->provisioning_voip_subscriber) { - $c->log->error("invalid subscriber_id '$subscriber_id'"); # TODO: user, message, trace, ... - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Subscriber does not exist"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Subscriber does not exist", + "invalid subscriber_id '$subscriber_id'"); return; } return $sub; diff --git a/lib/NGCP/Panel/Role/API/ResellerBrandings.pm b/lib/NGCP/Panel/Role/API/ResellerBrandings.pm index cf74be3d13..0887a840e1 100644 --- a/lib/NGCP/Panel/Role/API/ResellerBrandings.pm +++ b/lib/NGCP/Panel/Role/API/ResellerBrandings.pm @@ -126,8 +126,8 @@ sub check_resource{ my $reseller = $c->model('DB')->resultset('resellers')->find($resource->{reseller_id}); unless($reseller) { - $c->log->error("invalid reseller_id '".((defined $resource->{reseller_id})?$resource->{reseller_id} : "undefined")."', does not exist"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid reseller_id, does not exist"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid reseller_id, does not exist", + "invalid reseller_id '".((defined $resource->{reseller_id})?$resource->{reseller_id} : "undefined")."', does not exist"); return; } @@ -142,8 +142,8 @@ sub check_duplicate{ reseller_id => $resource->{reseller_id}, }); if($existing_item && (!$item || $item->id != $existing_item->id)) { - $c->log->error("Branding already exists for reseller_id '$$resource{reseller_id}'"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Branding already exists for this reseller"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Branding already exists for this reseller", + "Branding already exists for reseller_id '$$resource{reseller_id}'"); return; } return 1; diff --git a/lib/NGCP/Panel/Role/API/ResellerPhonebookEntries.pm b/lib/NGCP/Panel/Role/API/ResellerPhonebookEntries.pm index 3049daaf3c..1ef50944e5 100644 --- a/lib/NGCP/Panel/Role/API/ResellerPhonebookEntries.pm +++ b/lib/NGCP/Panel/Role/API/ResellerPhonebookEntries.pm @@ -51,14 +51,12 @@ sub check_resource { }); unless ($check_rs->first) { - $c->log->error("Invalid 'reseller_id'"); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid 'reseller_id'"); return; } } unless ($resource->{reseller_id}) { - $c->log->error("Required 'reseller_id'"); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Required 'reseller_id'"); return; } @@ -70,7 +68,6 @@ sub check_resource { })->first; if ($exists) { - $c->log->error("Duplicate entry 'reseller_id-number"); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Duplicate entry 'reseller_id-number"); return; } diff --git a/lib/NGCP/Panel/Role/API/RewriteRuleSets.pm b/lib/NGCP/Panel/Role/API/RewriteRuleSets.pm index 83756c26b7..9fb868d29f 100644 --- a/lib/NGCP/Panel/Role/API/RewriteRuleSets.pm +++ b/lib/NGCP/Panel/Role/API/RewriteRuleSets.pm @@ -127,8 +127,7 @@ sub update_rewriterules{ %{ $rule }, }); } catch($e) { - $c->log->error("failed to create rewriterules: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create rewrite rules."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create rewrite rules.", $e); die; } } diff --git a/lib/NGCP/Panel/Role/API/SoundFiles.pm b/lib/NGCP/Panel/Role/API/SoundFiles.pm index 409317ecc4..d3aa8aa7a9 100644 --- a/lib/NGCP/Panel/Role/API/SoundFiles.pm +++ b/lib/NGCP/Panel/Role/API/SoundFiles.pm @@ -27,8 +27,7 @@ sub transcode_data { unlink($filename); } catch($e) { unlink($filename); - $c->log->error("failed to transcode file: $e"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Failed to transcode file"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Failed to transcode file", $e); return; } return $resource; @@ -144,8 +143,8 @@ sub update_item { $resource->{loopplay} = ($resource->{loopplay} eq "true" || is_int($resource->{loopplay}) && $resource->{loopplay}) ? 1 : 0; if ($resource->{data} && !$resource->{filename}) { - $c->log->error("filename is required when there is data to upload'"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "'filename' cannot be empty during upload"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "'filename' cannot be empty during upload", + "filename is required when there is data to upload'"); return; } @@ -160,15 +159,15 @@ sub update_item { } my $set = $set_rs->first; unless($set) { - $c->log->error("invalid set_id '$$resource{set_id}'"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Sound set does not exist"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Sound set does not exist", + "invalid set_id '$$resource{set_id}'"); return; } if ($c->user->roles eq 'subscriberadmin') { if (!$set->contract_id || $set->contract_id != $c->user->account_id) { - $c->log->error("Cannot modify read-only sound file that does not belong to this subscriberadmin"); - $self->error($c, HTTP_FORBIDDEN, "Cannot modify read-only sound file"); + $self->error($c, HTTP_FORBIDDEN, "Cannot modify read-only sound file", + "Cannot modify read-only sound file that does not belong to this subscriberadmin"); return; } } @@ -185,8 +184,8 @@ sub update_item { $handle = $handle_rs->first; $resource->{handle} //= ''; unless($handle) { - $c->log->error("invalid handle '$$resource{handle}'"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid handle"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid handle", + "invalid handle '$$resource{handle}'"); return; } $resource->{handle_id} = $handle->id; @@ -196,8 +195,8 @@ sub update_item { try { NGCP::Panel::Utils::Sems::clear_audio_cache($c, $set->id, $handle->name, $group_name); } catch ($e) { - $c->log->error("Failed to clear audio cache for " . $group_name . " at appserver",); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, 'Failed to clear audio cache.'); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, 'Failed to clear audio cache.', + "Failed to clear audio cache for " . $group_name . " at appserver",); return; } @@ -207,7 +206,6 @@ sub update_item { $resource->{data} = $recording; $resource = $self->transcode_data($c, $from_codec, $resource); unless ($resource) { - $c->log->error("Failed to transcode sound file",); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, 'Failed to transcode sound file'); return; } @@ -222,8 +220,7 @@ sub update_item { $item = $c->model('DB')->resultset('voip_sound_files')->create($resource); } } catch($e) { - $c->log->error("failed to create soundfile: $e"); # TODO: user, message, trace, ... - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create soundfile."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create soundfile.", $e); return; } diff --git a/lib/NGCP/Panel/Role/API/SoundSets.pm b/lib/NGCP/Panel/Role/API/SoundSets.pm index b2cbae6ad5..d31066e9a7 100644 --- a/lib/NGCP/Panel/Role/API/SoundSets.pm +++ b/lib/NGCP/Panel/Role/API/SoundSets.pm @@ -116,8 +116,8 @@ sub check_resource{ id => $resource->{reseller_id}, }); unless($reseller) { - $c->log->error("invalid reseller_id '$$resource{reseller_id}'"); # TODO: user, message, trace, ... - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Reseller does not exist"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Reseller does not exist", + "invalid reseller_id '$$resource{reseller_id}'"); return; } my $customer; @@ -129,34 +129,34 @@ sub check_resource{ join => 'contact', }); unless($customer) { - $c->log->error("invalid customer_id '$$resource{contract_id}'"); # TODO: user, message, trace, ... - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Customer does not exist"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Customer does not exist", + "invalid customer_id '$$resource{contract_id}'"); return; } unless($customer->contact->reseller_id == $reseller->id) { - $c->log->error("customer_id '$$resource{contract_id}' doesn't belong to reseller_id '$$resource{reseller_id}"); # TODO: user, message, trace, ... - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid reseller for customer"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid reseller for customer", + "customer_id '$$resource{contract_id}' doesn't belong to reseller_id '$$resource{reseller_id}"); return; } } if ($c->user->roles eq 'subscriberadmin' && $c->request->method ne 'POST' && (!$old_resource->{contract_id} || $old_resource->{contract_id} != $c->user->account_id)) { - $c->log->error("Cannot modify read-only sound set that does not belong to this subscriberadmin"); - $self->error($c, HTTP_FORBIDDEN, "Cannot modify read-only sound set"); + $self->error($c, HTTP_FORBIDDEN, "Cannot modify read-only sound set", + "Cannot modify read-only sound set that does not belong to this subscriberadmin"); return; } if ($resource->{parent_id}) { my $parent = $c->model('DB')->resultset('voip_sound_sets')->find($resource->{parent_id}); if (!$parent) { - $c->log->error("Invalid parent_id '$$resource{parent_id}'"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Parent sound set does not exist"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Parent sound set does not exist", + "Invalid parent_id '$$resource{parent_id}'"); return; } if ($c->user->roles ne 'admin' && $reseller->id != $parent->reseller_id) { - $c->log->error("parent_id '$$resource{parent_id}' doesn't belong to reseller_id '$$resource{reseller_id}"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid reseller for parent sound set"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid reseller for parent sound set", + "parent_id '$$resource{parent_id}' doesn't belong to reseller_id '$$resource{reseller_id}"); return; } if ($c->req->method eq 'PUT' || $c->req->method eq 'PATCH') { @@ -164,8 +164,8 @@ sub check_resource{ $c, $old_resource->{id}, $resource->{parent_id} ); if ($loop) { - $c->log->error("parent_id '$$resource{parent_id}' one of the parent sound sets refers to this one as a parent"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Cannot use the parent sound set"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Cannot use the parent sound set", + "parent_id '$$resource{parent_id}' one of the parent sound sets refers to this one as a parent"); return; } } diff --git a/lib/NGCP/Panel/Role/API/SpeedDials.pm b/lib/NGCP/Panel/Role/API/SpeedDials.pm index c99d42c494..29df0c4c98 100644 --- a/lib/NGCP/Panel/Role/API/SpeedDials.pm +++ b/lib/NGCP/Panel/Role/API/SpeedDials.pm @@ -147,8 +147,7 @@ sub update_item { }); } } catch($e) { - $c->log->error("failed to update speeddials: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to update speeddials."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to update speeddials.", $e); return; }; diff --git a/lib/NGCP/Panel/Role/API/SubscriberLocationMappings.pm b/lib/NGCP/Panel/Role/API/SubscriberLocationMappings.pm index ddee83e1a7..ea1c83751f 100644 --- a/lib/NGCP/Panel/Role/API/SubscriberLocationMappings.pm +++ b/lib/NGCP/Panel/Role/API/SubscriberLocationMappings.pm @@ -105,8 +105,8 @@ sub update_item { } my $sub = $sub_rs->first; unless($sub && $sub->provisioning_voip_subscriber) { - $c->log->error("invalid subscriber_id '$$resource{subscriber_id}'"); # TODO: user, message, trace, ... - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Subscriber does not exist"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Subscriber does not exist", + "invalid subscriber_id '$$resource{subscriber_id}'"); return; } $resource->{subscriber_id} = $sub->provisioning_voip_subscriber->id; diff --git a/lib/NGCP/Panel/Role/API/SubscriberPhonebookEntries.pm b/lib/NGCP/Panel/Role/API/SubscriberPhonebookEntries.pm index 48bb8aa6c4..314cb29a5d 100644 --- a/lib/NGCP/Panel/Role/API/SubscriberPhonebookEntries.pm +++ b/lib/NGCP/Panel/Role/API/SubscriberPhonebookEntries.pm @@ -75,7 +75,6 @@ sub check_resource { } unless ($check_rs->first) { - $c->log->error("Invalid 'subscriber_id'"); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid 'subscriber_id'"); return; } @@ -86,7 +85,6 @@ sub check_resource { } unless ($resource->{subscriber_id}) { - $c->log->error("Required 'subscriber_id'"); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Required 'subscriber_id'"); return; } @@ -98,7 +96,6 @@ sub check_resource { })->first; if ($exists) { - $c->log->error("Duplicate entry 'subscriber_id-number"); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Duplicate entry 'subscriber_id-number"); return; } diff --git a/lib/NGCP/Panel/Role/API/SubscriberProfileSets.pm b/lib/NGCP/Panel/Role/API/SubscriberProfileSets.pm index e531b09074..dd6373c501 100644 --- a/lib/NGCP/Panel/Role/API/SubscriberProfileSets.pm +++ b/lib/NGCP/Panel/Role/API/SubscriberProfileSets.pm @@ -96,8 +96,8 @@ sub update_item { name => $resource->{name}, }); if($dup_item && $dup_item->id != $item->id) { - $c->log->error("subscriber profile set with name '$$resource{name}' already exists for reseller_id '$$resource{reseller_id}'"); # TODO: user, message, trace, ... - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Subscriber profile set with this name already exists for this reseller"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Subscriber profile set with this name already exists for this reseller", + "subscriber profile set with name '$$resource{name}' already exists for reseller_id '$$resource{reseller_id}'"); return; } diff --git a/lib/NGCP/Panel/Role/API/SubscriberProfiles.pm b/lib/NGCP/Panel/Role/API/SubscriberProfiles.pm index 8cb5ef44ab..89f2e05ee2 100644 --- a/lib/NGCP/Panel/Role/API/SubscriberProfiles.pm +++ b/lib/NGCP/Panel/Role/API/SubscriberProfiles.pm @@ -120,8 +120,8 @@ sub update_item { $set = $set->find($resource->{set_id}); unless($set) { - $c->log->error("subscriber profile set id '$$resource{set_id}' does not exist"); # TODO: user, message, trace, ... - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid 'profile_set_id', does not exist"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid 'profile_set_id', does not exist", + "subscriber profile set id '$$resource{set_id}' does not exist"); return; } @@ -129,8 +129,9 @@ sub update_item { name => $resource->{name}, }); if($dup_item && $dup_item->id != $item->id) { - $c->log->error("subscriber profile with name '$$resource{name}' already exists for profile_set_id '$$resource{set_id}'"); # TODO: user, message, trace, ... - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Subscriber profile with this name already exists for this profile set"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, + "Subscriber profile with this name already exists for this profile set", + "subscriber profile with name '$$resource{name}' already exists for profile_set_id '$$resource{set_id}'"); return; } diff --git a/lib/NGCP/Panel/Role/API/Subscribers.pm b/lib/NGCP/Panel/Role/API/Subscribers.pm index 8b2a67c5de..0f90df19e2 100644 --- a/lib/NGCP/Panel/Role/API/Subscribers.pm +++ b/lib/NGCP/Panel/Role/API/Subscribers.pm @@ -193,7 +193,7 @@ sub resource_from_item { } }; if ($@) { - $c->log->error("Failed to encrypt $k: " . $@); + $c->error("Failed to encrypt $k: " . $@); delete $resource{'_' . $k}; } } @@ -434,8 +434,8 @@ sub update_item { NGCP::Panel::Utils::Subscriber::terminate(c => $c, subscriber => $subscriber); return $subscriber; } catch($e) { - $c->log->error("failed to terminate subscriber id ".$subscriber->id . ": $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to terminate subscriber"); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to terminate subscriber", + "failed to terminate subscriber id ".$subscriber->id, $e); return; } } @@ -447,15 +447,14 @@ sub update_item { level => $resource->{lock} || 0, ); } catch($e) { - $c->log->error("failed to lock subscriber id ".$subscriber->id." with level ".$resource->{lock}); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to update subscriber lock"); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to update subscriber lock", + "failed to lock subscriber id ".$subscriber->id." with level ".$resource->{lock}, $e); return; }; my ($error,$profile_set,$profile) = NGCP::Panel::Utils::Subscriber::check_profile_set_and_profile($c, $resource, $subscriber); if ($error) { - $c->log->error($error->{error}); - $self->error($c, $error->{response_code}, $error->{description}); + $self->error($c, $error->{response_code}, $error->{description}, $error->{error}); return; } @@ -506,22 +505,21 @@ sub update_item { ); } catch(DBIx::Class::Exception $e where { /Duplicate entry '([^']+)' for key 'number_idx'/ }) { $e =~ /Duplicate entry '([^']+)' for key 'number_idx'/; - $c->log->error("failed to update subscriber, number " . $c->qs($1) . " already exists"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Number '" . $1 . "' already exists.", "Number already exists."); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Number '" . $1 . "' already exists.", "Number already exists.", + "failed to update subscriber, number " . $c->qs($1) . " already exists"); return; } catch ($e where { /alias \d+ already exists/ }) { $e =~ /alias (\d+) already exists/; - $c->log->error("failed to update subscriber, alias " . $c->qs($1) . " already exists"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Number '" . $1 . "' already exists.", "Number already exists."); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Number '" . $1 . "' already exists.", "Number already exists.", + "failed to update subscriber, alias " . $c->qs($1) . " already exists"); return; } catch ($e where { /aliases \S+ already exist/ }) { $e =~ /aliases (\S+) already exist/; - $c->log->error("failed to update subscriber, aliases " . $c->qs($1) . " already exist"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Numbers '" . $1 . "' already exist.", "Numbers already exist."); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Numbers '" . $1 . "' already exist.", "Numbers already exist.", + "failed to update subscriber, aliases " . $c->qs($1) . " already exist"); return; } catch ($e where { /more than \d+ provided aliases/ }) { my $err_msg = "more than 10 provided aliases already exist"; - $c->log->error($err_msg); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, $err_msg); return; } diff --git a/lib/NGCP/Panel/Role/API/TimeSets.pm b/lib/NGCP/Panel/Role/API/TimeSets.pm index 7d310190eb..400b8daad4 100644 --- a/lib/NGCP/Panel/Role/API/TimeSets.pm +++ b/lib/NGCP/Panel/Role/API/TimeSets.pm @@ -116,8 +116,8 @@ sub check_duplicate { name => $resource->{name}, }); if ($existing_item && (!$item || $item->id != $existing_item->id)) { - $c->log->error("time_set name '$$resource{name}' already exists"); - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "time_set with this name already exists"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "time_set with this name already exists", + "time_set name '$$resource{name}' already exists"); return; } return 1; @@ -134,8 +134,7 @@ sub update_item_model { ); $item->discard_changes; } catch($e) { - $c->log->error("failed to update timeset: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to update timesets."); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to update timesets.", $e); return; }; diff --git a/lib/NGCP/Panel/Role/API/TrustedSources.pm b/lib/NGCP/Panel/Role/API/TrustedSources.pm index d1c6e9f0fc..92b5662d6f 100644 --- a/lib/NGCP/Panel/Role/API/TrustedSources.pm +++ b/lib/NGCP/Panel/Role/API/TrustedSources.pm @@ -107,8 +107,8 @@ sub update_item { } my $sub = $sub_rs->first; unless($sub && $sub->provisioning_voip_subscriber) { - $c->log->error("invalid subscriber_id '$$resource{subscriber_id}'"); # TODO: user, message, trace, ... - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Subscriber does not exist"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Subscriber does not exist", + "invalid subscriber_id '$$resource{subscriber_id}'"); return; } $resource->{subscriber_id} = $sub->provisioning_voip_subscriber->id; diff --git a/lib/NGCP/Panel/Role/API/UpnRewriteSets.pm b/lib/NGCP/Panel/Role/API/UpnRewriteSets.pm index 2c1db86a7b..1d56db649f 100644 --- a/lib/NGCP/Panel/Role/API/UpnRewriteSets.pm +++ b/lib/NGCP/Panel/Role/API/UpnRewriteSets.pm @@ -114,15 +114,15 @@ sub update_item { my $sub = $sub_rs->first; unless($sub && $sub->provisioning_voip_subscriber) { my $debug_sid = $resource->{subscriber_id} // '(undef)'; - $c->log->error("invalid subscriber_id '$debug_sid'"); # TODO: user, message, trace, ... - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Subscriber does not exist"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Subscriber does not exist", + "invalid subscriber_id '$debug_sid'"); return; } $resource->{subscriber_id} = $sub->provisioning_voip_subscriber->id; unless($resource->{subscriber_id} == $item->subscriber_id) { - $c->log->error("cannot edit subscriber_id '$$resource{subscriber_id}'"); # TODO: user, message, trace, ... - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "subscriber_id cannot be changed"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "subscriber_id cannot be changed", + "cannot edit subscriber_id '$$resource{subscriber_id}'"); return; } diff --git a/lib/NGCP/Panel/Role/API/VoicemailSettings.pm b/lib/NGCP/Panel/Role/API/VoicemailSettings.pm index 87a63c205c..8bdfbf08f2 100644 --- a/lib/NGCP/Panel/Role/API/VoicemailSettings.pm +++ b/lib/NGCP/Panel/Role/API/VoicemailSettings.pm @@ -93,7 +93,7 @@ sub resource_from_item { $resource->{$k} = NGCP::Panel::Utils::Encryption::encrypt_rsa($c,$resource->{$k}); }; if ($@) { - $c->log->error("Failed to encrypt $k '$resource->{$k}': " . $@); + $c->error("Failed to encrypt $k '$resource->{$k}': " . $@); delete $resource->{$k}; } } @@ -119,7 +119,7 @@ sub update_item { $resource->{$k} = NGCP::Panel::Utils::Encryption::decrypt_rsa($c,$resource->{$k}); }; if ($@) { - $c->log->error("Failed to encrypt $k '$resource->{$k}': " . $@); + $c->error("Failed to encrypt $k '$resource->{$k}': " . $@); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Failed to encrypt $k."); return; } diff --git a/lib/NGCP/Panel/Role/API/Vouchers.pm b/lib/NGCP/Panel/Role/API/Vouchers.pm index 7b81ae4a99..615305f3d9 100644 --- a/lib/NGCP/Panel/Role/API/Vouchers.pm +++ b/lib/NGCP/Panel/Role/API/Vouchers.pm @@ -114,8 +114,8 @@ sub update_item { code => $code, }); if($dup_item && $dup_item->id != $item->id) { - $c->log->error("voucher with code '$$resource{code}' already exists for reseller_id '$$resource{reseller_id}'"); # TODO: user, message, trace, ... - $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Voucher with this code already exists for this reseller"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Voucher with this code already exists for this reseller", + "voucher with code '$$resource{code}' already exists for reseller_id '$$resource{reseller_id}'"); return; } $resource->{code} = $code; diff --git a/lib/NGCP/Panel/Role/Entities.pm b/lib/NGCP/Panel/Role/Entities.pm index f18ff34db6..8cf67a07c3 100644 --- a/lib/NGCP/Panel/Role/Entities.pm +++ b/lib/NGCP/Panel/Role/Entities.pm @@ -244,69 +244,121 @@ sub get { sub post { my ($self) = shift; my ($c) = @_; - my $guard = $self->get_transaction_control($c); - { - #instead of type parameter get_form can check request method - my ($form) = $self->get_form($c, 'add'); - my $method_config = $self->get_config('action')->{POST}; - my $process_extras= {}; - my ($resource, $data, $non_json_data) = $self->get_valid_data( - c => $c, - method => 'POST', - media_type => $method_config->{ContentType} // 'application/json', - uploads => $method_config->{Uploads} // [] , - form => $form, - resource_media_type => $method_config->{ResourceContentType}, - ); - last unless $resource; - my ($item,$data_processed_result,$hal,$id); - if (!$non_json_data || !$data) { - delete $resource->{purge_existing}; - last unless $self->pre_process_form_resource($c, undef, undef, $resource, $form, $process_extras); - last unless $self->validate_form( - c => $c, - resource => $resource, - form => $form, + + my $method_config = $self->get_config('action')->{POST}; + my $process_extras= {}; + my ($resource, $item, $form, $hal, $hal_id); + + TX_START: + try { + $c->clear_errors; + $form = $self->get_form($c, 'add'); + + my $guard = $self->start_transaction($c); + { + my ($data, $non_json_data); + ($resource, $data, $non_json_data) = $self->get_valid_data( + c => $c, + method => 'POST', + media_type => $method_config->{ContentType} // 'application/json', + uploads => $method_config->{Uploads} // [] , + form => $form, + resource_media_type => $method_config->{ResourceContentType}, ); - last unless $self->process_form_resource($c, undef, undef, $resource, $form, $process_extras); - last unless $resource; - last unless $self->check_duplicate($c, undef, undef, $resource, $form, $process_extras); - last unless $self->check_resource($c, undef, undef, $resource, $form, $process_extras); + unless ($resource) { + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, 'Could not validate request data', + '#get_valid_data') unless $c->has_errors; + goto TX_END; + } - $item = $self->create_item($c, $resource, $form, $process_extras); - last unless $item || $self->get_config('no_item_created'); + if (!$non_json_data || !$data) { + delete $resource->{purge_existing}; - ($hal, $id) = $self->get_journal_item_hal($c, $item, { form => $form }); - last unless $self->add_journal_item_hal($c, { hal => $hal, ($id ? ( id => $id, ) : ()) }); + unless ($self->pre_process_form_resource($c, undef, undef, $resource, $form, $process_extras)) { + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, 'Could not validate request data', + '#pre_process_form_resource') unless $c->has_errors; + goto TX_END; + } - } else { - try { - #$processed_ok(array), $processed_failed(array), $info, $error - $data_processed_result = $self->process_data( - c => $c, - data => \$data, + return unless $self->validate_form( + c => $c, resource => $resource, - form => $form, - process_extras => $process_extras, + form => $form, ); - } catch($e) { - $c->log->error("failed to process non json data: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error"); - last; - }; - } - $self->complete_transaction($c); - $self->post_process_commit($c, 'create', $item, undef, $resource, $form, $process_extras); + unless ($self->process_form_resource($c, undef, undef, $resource, $form, $process_extras)) { + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, 'Could not validate request data', + '#pre_process_form_resource') unless $c->has_errors; + goto TX_END; + } - return if defined $c->stash->{api_error_message}; + unless ($self->check_duplicate($c, undef, undef, $resource, $form, $process_extras)) { + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, 'Could not validate request data', + '#check_duplicates') unless $c->has_errors; + goto TX_END; + } - $self->return_representation_post($c, - 'hal' => $hal, - 'item' => $item, - 'form' => $form - ); + unless ($self->check_resource($c, undef, undef, $resource, $form, $process_extras)) { + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, 'Could not validate request data', + '#check_resource') unless $c->has_errors; + goto TX_END; + } + + $item = $self->create_item($c, $resource, $form, $process_extras); + unless ($item || $self->get_config('no_item_created')) { + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, 'Internal Server Error', + '#create_item') unless $c->has_errors; + goto TX_END; + } + + ($hal, $hal_id) = $self->get_journal_item_hal($c, $item, { form => $form }); + unless ($self->add_journal_item_hal($c, { hal => $hal, ($hal_id ? ( id => $hal_id, ) : ()) })) { + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, 'Internal Server Error', + '#add_journal_item_hal') unless $c->has_errors; + goto TX_END; + } + } else { + try { + #$processed_ok(array), $processed_failed(array), $info, $error + my $data_processed_result = $self->process_data( + c => $c, + data => \$data, + resource => $resource, + form => $form, + process_extras => $process_extras, + ); + } catch($e) { + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error", + "failed to process non json data", $e); + return; + }; + } + $self->commit_transaction($c, $guard); + } + + TX_END: + if ($c->has_errors) { # something went wrong without triggering an exception + $self->check_deadlock($c, $c->last_error) and goto TX_START; + return; + } + } catch($e) { + $self->check_deadlock($c, $e) and goto TX_START; + unless ($c->has_errors) { + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, 'Internal Server Error', $e); + } + return; } + + $self->post_process_commit($c, 'create', $item, undef, $resource, $form, $process_extras); + + return if $c->has_errors; + + $self->return_representation_post($c, + 'hal' => $hal, + 'item' => $item, + 'form' => $form + ); + return; } diff --git a/lib/NGCP/Panel/Role/EntitiesItem.pm b/lib/NGCP/Panel/Role/EntitiesItem.pm index 5628abbd8d..3bf4330a60 100644 --- a/lib/NGCP/Panel/Role/EntitiesItem.pm +++ b/lib/NGCP/Panel/Role/EntitiesItem.pm @@ -15,6 +15,7 @@ use NGCP::Panel::Utils::Generic qw(:all); use NGCP::Panel::Utils::DateTime; use NGCP::Panel::Utils::ValidateJSON qw(); use TryCatch; + ##### --------- common part sub auto :Private { @@ -253,148 +254,267 @@ sub get { sub patch { my ($self, $c, $id) = @_; - my $guard = $self->get_transaction_control($c); - { - my $preference = $self->require_preference($c); - last unless $preference; - - my ($form, $process_extras); - ($form) = $self->get_form($c, 'edit'); - - my $method_config = $self->get_config('action')->{PATCH}; - my $patch_ops = ref $method_config eq 'HASH' && defined $method_config->{ops} ? $method_config->{ops} : [qw/replace copy/]; - my $json = $self->get_valid_patch_data( - c => $c, - id => $id, - media_type => 'application/json-patch+json', - form => $form, - ops => $patch_ops, - ); - last unless $json; + my $preference = $self->require_preference($c); + return unless $preference; + + my ($form, $process_extras); + $form = $self->get_form($c, 'edit'); + + my $method_config = $self->get_config('action')->{PATCH}; + my $patch_ops = ref $method_config eq 'HASH' && defined $method_config->{ops} ? $method_config->{ops} : [qw/replace copy/]; + my $json = $self->get_valid_patch_data( + c => $c, + id => $id, + media_type => 'application/json-patch+json', + form => $form, + ops => $patch_ops, + ); + unless ($json) { + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, 'Could not validate request data', + '#get_valid_patch_data') unless $c->has_errors; + return; + } - my $item = $self->item_by_id_valid($c, $id); - last unless $item; - my $old_resource = $self->resource_from_item($c, $item); - #$old_resource = clone($old_resource); - ##without it error: The entity could not be processed: Modification of a read-only value attempted at /usr/share/perl5/JSON/Pointer.pm line 200, <$fh> line 1.\n - my $resource = $self->apply_patch($c, $old_resource, $json); - last unless $resource; + my ($item, $old_resource, $resource, $hal, $hal_id); + + TX_START: + try { + $c->clear_errors; + # re-request form as it apparently gets changed within the transaction in overloaded update_item() for instance + $form = $self->get_form($c, 'edit'); + + my $guard = $self->start_transaction($c); + { + $item = $self->item_by_id_valid($c, $id); + unless ($item) { + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, 'Could not validate request data', + '#item_by_id_valid') unless $c->has_errors; + goto TX_END; + } - ($item, $form, $process_extras) = $self->update_item($c, $item, $old_resource, $resource, $form, $process_extras ); - last unless $item; + $old_resource = $self->resource_from_item($c, $item); + #$old_resource = clone($old_resource); + ##without it error: The entity could not be processed: Modification of a read-only value attempted at /usr/share/perl5/JSON/Pointer.pm line 200, <$fh> line 1.\n + $resource = $self->apply_patch($c, $old_resource, $json); + unless ($resource) { + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, 'Internal Server Error', + '#apply_patch') unless $c->has_errors; + goto TX_END; + } + + ($item, $form, $process_extras) = $self->update_item($c, $item, $old_resource, $resource, $form, $process_extras ); + unless ($item) { + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, 'Internal Server Error', + '#update_item') unless $c->has_errors; + goto TX_END; + } - my $hal; - ($hal,$id) = $self->get_journal_item_hal($c, $item, { form => $form }); - last unless $self->add_journal_item_hal($c, { hal => $hal, ($id ? ( id => $id, ) : ()) }); + ($hal, $hal_id) = $self->get_journal_item_hal($c, $item, { form => $form }); + unless ($self->add_journal_item_hal($c, { hal => $hal, ($hal_id ? ( id => $hal_id, ) : ()) })) { + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, 'Internal Server Error', + '#add_journal_item_hal') unless $c->has_errors; + goto TX_END; + } - $self->complete_transaction($c); - $self->post_process_commit($c, 'patch', $item, $old_resource, $resource, $form, $process_extras); + $self->commit_transaction($c, $guard); + } - $self->return_representation($c, - 'item' => $item, - 'form' => $form, - #hal may be empty if we don't need it for journal. - #Then it will be taken from item and form - 'hal' => $hal, - 'preference' => $preference, - ); + TX_END: + if ($c->has_errors) { # something went wrong without triggering an exception + $self->check_deadlock($c, $c->last_error) and goto TX_START; + return; + } + } catch($e) { + $self->check_deadlock($c, $e) and goto TX_START; + unless ($c->has_errors) { + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, 'Internal Server Error', $e); + } + return; } + + $self->post_process_commit($c, 'patch', $item, $old_resource, $resource, $form, $process_extras); + + return if $c->has_errors; + + $self->return_representation($c, + 'item' => $item, + 'form' => $form, + #hal may be empty if we don't need it for journal. + #Then it will be taken from item and form + 'hal' => $hal, + 'preference' => $preference, + ); + return; } sub put { my ($self, $c, $id) = @_; - my $guard = $self->get_transaction_control($c); - { - my $preference = $self->require_preference($c); - last unless $preference; - #$old_resource = clone($old_resource); - ##without it error: The entity could not be processed: Modification of a read-only value attempted at /usr/share/perl5/JSON/Pointer.pm line 200, <$fh> line 1.\n - my ($form, $process_extras); - ($form) = $self->get_form($c, 'edit'); + my $preference = $self->require_preference($c); + return unless $preference; + + #$old_resource = clone($old_resource); + ##without it error: The entity could not be processed: Modification of a read-only value attempted at /usr/share/perl5/JSON/Pointer.pm line 200, <$fh> line 1.\n + my ($form, $process_extras); + $form = $self->get_form($c, 'edit'); + + my $method_config = $self->get_config('action')->{PUT}; + my ($resource, $data, $non_json_data) = $self->get_valid_data( + c => $c, + id => $id, + method => 'PUT', + media_type => $method_config->{ContentType} // 'application/json', + uploads => $method_config->{Uploads} // [] , + form => $form, + ); + unless ($resource) { + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, 'Could not validate request data', + '#get_valid_data') unless $c->has_errors; + return; + } - my $item = $self->item_by_id_valid($c, $id); - last unless $item; - my $method_config = $self->get_config('action')->{PUT}; - my ($resource, $data, $non_json_data) = $self->get_valid_data( - c => $c, - id => $id, - method => 'PUT', - media_type => $method_config->{ContentType} // 'application/json', - uploads => $method_config->{Uploads} // [] , - form => $form, - ); - last unless $resource; - my $old_resource = $self->resource_from_item($c, $item); + my ($item, $old_resource, $hal, $hal_id); + + TX_START: + try { + $c->clear_errors; + # re-request form as it apparently gets changed within the transaction in overloaded update_item() for instance + $form = $self->get_form($c, 'edit'); + + my $guard = $self->start_transaction($c); + { + $item = $self->item_by_id_valid($c, $id); + unless ($item) { + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, 'Could not validate request data', + '#item_by_id_valid') unless $c->has_errors; + goto TX_END; + } - my ($data_processed_result); - if (!$non_json_data || !$data) { - ($item, $form, $process_extras) = $self->update_item($c, $item, $old_resource, $resource, $form, $process_extras ); - last unless $item; - } else { - try { - #$processed_ok(array), $processed_failed(array), $info, $error - $data_processed_result = $self->process_data( - c => $c, - item => $item, - data => \$data, - resource => $resource, - form => $form, - process_extras => $process_extras, - ); - } catch($e) { - $c->log->error("failed to process non json data: $e"); - $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error"); - last; - }; + $old_resource = $self->resource_from_item($c, $item); + + my ($data_processed_result); + if (!$non_json_data || !$data) { + ($item, $form, $process_extras) = $self->update_item($c, $item, $old_resource, $resource, $form, $process_extras ); + unless ($item) { + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, 'Internal Server Error', + '#update_item') unless $c->has_errors; + goto TX_END; + } + } else { + try { + #$processed_ok(array), $processed_failed(array), $info, $error + $data_processed_result = $self->process_data( + c => $c, + item => $item, + data => \$data, + resource => $resource, + form => $form, + process_extras => $process_extras, + ); + } catch($e) { + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, 'Internal Server Error', + "failed to process non json data", $e); + goto TX_END; + }; + } + + ($hal, $hal_id) = $self->get_journal_item_hal($c, $item, { form => $form }); + unless ($self->add_journal_item_hal($c, { hal => $hal, ($hal_id ? ( id => $hal_id, ) : ()) })) { + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, 'Internal Server Error', + '#add_journal_item_hal') unless $c->has_errors; + goto TX_END; + } + + $self->commit_transaction($c, $guard); } - my $hal; - ($hal,$id) = $self->get_journal_item_hal($c, $item, { form => $form }); - last unless $self->add_journal_item_hal($c, { hal => $hal, ($id ? ( id => $id, ) : ()) }); - - $self->complete_transaction($c); - $self->post_process_commit($c, 'put', $item, $old_resource, $resource, $form, $process_extras); - $self->return_representation($c, - #hal may be empty if we don't need it for journal. - #Then it will be taken from item and form - 'hal' => $hal, - 'item' => $item, - 'form' => $form, - 'preference' => $preference, - ); + TX_END: + if ($c->has_errors) { # something went wrong without triggering an exception + $self->check_deadlock($c, $c->last_error) and goto TX_START; + return; + } + } catch($e) { + $self->check_deadlock($c, $e) and goto TX_START; + unless ($c->has_errors) { + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, 'Internal Server Error', $e); + } + return; } + + $self->post_process_commit($c, 'put', $item, $old_resource, $resource, $form, $process_extras); + + return if $c->has_errors; + + $self->return_representation($c, + #hal may be empty if we don't need it for journal. + #Then i will be taken from item and form + 'hal' => $hal, + 'item' => $item, + 'form' => $form, + 'preference' => $preference, + ); + return; } sub delete { ## no critic (ProhibitBuiltinHomonyms) my ($self, $c, $id) = @_; - my $guard = $self->get_transaction_control($c); - { - my $item = $self->item_by_id_valid($c, $id); - last unless $item; + my ($item, $hal, $hal_id); + + TX_START: + try { + my $guard = $self->start_transaction($c); + { + $item = $self->item_by_id_valid($c, $id); + unless ($item) { + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, 'Could not validate request data', + '#item_by_id_valid'); + goto TX_END; + } - my $hal; - ($hal,$id) = $self->get_journal_item_hal($c, $item); - #here we left space for information that checking failed and we decided not to delete item - if ($self->delete_item($c, $item)) { - $self->add_journal_item_hal($c, { hal => $hal, ($id ? ( id => $id, ) : ()) }); - } else { + ($hal, $hal_id) = $self->get_journal_item_hal($c, $item); + #here we left space for information that checking failed and we decided not to delete item + if ($self->delete_item($c, $item)) { + unless ($self->add_journal_item_hal($c, { hal => $hal, ($hal_id ? ( id => $hal_id, ) : ()) })) { + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, 'Internal Server Error', + '#add_journal_item_hal'); + goto TX_END; + } + } else { + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, 'Internal Server Error', + 'non 1 return from $self->delete_item()'); + goto TX_END; + } + + $self->commit_transaction($c, $guard); + } + + TX_END: + if ($c->has_errors) { # something went wrong without triggering an exception + $self->check_deadlock($c, $c->last_error) and goto TX_START; return; } + } catch($e) { + $self->check_deadlock($c, $e) and goto TX_START; + unless ($c->has_errors) { + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, 'Internal Server Error', $e); + } + return; + } - $self->complete_transaction($c); - $self->post_process_commit($c, 'delete', $item); + $self->post_process_commit($c, 'delete', $item); + + return if $c->has_errors; + + $c->response->status(HTTP_NO_CONTENT); + $c->response->body(q()); - $c->response->status(HTTP_NO_CONTENT); - $c->response->body(q()); - } return; } -sub delete_item{ +sub delete_item { my($self, $c, $item) = @_; $item->delete(); return 1; diff --git a/lib/NGCP/Panel/Utils/DeviceBootstrap/ALE.pm b/lib/NGCP/Panel/Utils/DeviceBootstrap/ALE.pm index 8565b50819..174987e00c 100644 --- a/lib/NGCP/Panel/Utils/DeviceBootstrap/ALE.pm +++ b/lib/NGCP/Panel/Utils/DeviceBootstrap/ALE.pm @@ -37,7 +37,7 @@ sub rest_prepare_request { $self->{rpc_server_params} //= $self->rpc_server_params; my $cfg = $self->{rpc_server_params}; - my $tx_id = $c->session->{api_request_tx_id} // + my $tx_id = $c->stash->{api_request_tx_id} // uc Data::UUID->create_str() =~ s/-//gr; $c->log->debug($self->to_log({ name => 'ALE prepare request', diff --git a/lib/NGCP/Panel/Utils/DeviceBootstrap/Snom.pm b/lib/NGCP/Panel/Utils/DeviceBootstrap/Snom.pm index 2c40ae491b..e11cd09be7 100644 --- a/lib/NGCP/Panel/Utils/DeviceBootstrap/Snom.pm +++ b/lib/NGCP/Panel/Utils/DeviceBootstrap/Snom.pm @@ -41,7 +41,7 @@ sub rest_prepare_request { }; my $company_url; - my $tx_id = $c->session->{api_request_tx_id} // + my $tx_id = $c->stash->{api_request_tx_id} // uc Data::UUID->create_str() =~ s/-//gr; $self->{rpc_server_params} //= $self->rpc_server_params; diff --git a/lib/NGCP/Panel/Utils/Journal.pm b/lib/NGCP/Panel/Utils/Journal.pm index 1c016b346f..0f965e6889 100644 --- a/lib/NGCP/Panel/Utils/Journal.pm +++ b/lib/NGCP/Panel/Utils/Journal.pm @@ -657,7 +657,7 @@ sub _create_journal { $journal{reseller_id} = $resource->{reseller_id} // $c->user->reseller_id; $journal{role_id} = NGCP::Panel::Utils::UserRole::resolve_role_id($c, $c->user); - $journal{tx_id} = $c->session->{api_request_tx_id}; + $journal{tx_id} = $c->stash->{api_request_tx_id}; try { $journal{content} = _serialize_content($content_format, $resource); diff --git a/lib/NGCP/Panel/Utils/Message.pm b/lib/NGCP/Panel/Utils/Message.pm index 0448e2dcfe..f890162cb8 100644 --- a/lib/NGCP/Panel/Utils/Message.pm +++ b/lib/NGCP/Panel/Utils/Message.pm @@ -23,14 +23,21 @@ sub get_log_params { $called = sprintf 'API[%s]/%s', $c->request->method, $c->request->path; - $c->session->{api_request_tx_id} = $log_tx_id; + $c->stash->{api_request_tx_id} = $log_tx_id; } elsif ($type eq 'api_response') { $called = sprintf 'API[%s %d]/%s', $c->request->method, $c->response->code, $c->request->path; - if ($c->session->{api_request_tx_id}) { - $log_tx_id = $c->session->{api_request_tx_id}; + if ($c->stash->{api_request_tx_id}) { + $log_tx_id = $c->stash->{api_request_tx_id}; + } + } elsif ($type eq 'api_retry') { + $called = sprintf 'API[%s]/%s', + $c->request->method, + $c->request->path; + if ($c->stash->{api_request_tx_id}) { + $log_tx_id = $c->stash->{api_request_tx_id}; } } else { my $caller = (caller 2)[3]; diff --git a/lib/NGCP/Panel/Utils/ProfilePackages.pm b/lib/NGCP/Panel/Utils/ProfilePackages.pm index d296f3fdc0..8a059b0d1c 100644 --- a/lib/NGCP/Panel/Utils/ProfilePackages.pm +++ b/lib/NGCP/Panel/Utils/ProfilePackages.pm @@ -555,7 +555,7 @@ sub create_topup_log_record { } elsif($c->user->roles eq 'subscriber' || $c->user->roles eq 'subscriberadmin') { $username = $c->user->webusername . '@' . $c->user->domain->domain; } - $message //= $c->stash->{api_error_message} // $c->stash->{panel_error_message}; + $message //= $c->has_errors ? join(', ', @{$c->error}) : ($c->stash->{panel_error_message} // ''); return $c->model('DB')->resultset('topup_logs')->create({ username => $username,