Skip to content

Commit b96096f

Browse files
committed
Improve telematics device sync and attach errors
1 parent 67eab99 commit b96096f

6 files changed

Lines changed: 374 additions & 62 deletions

File tree

‎server/src/Http/Controllers/Internal/v1/DeviceController.php‎

Lines changed: 75 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Fleetbase\FleetOps\Models\Vehicle;
88
use Illuminate\Http\JsonResponse;
99
use Illuminate\Http\Request;
10+
use Illuminate\Support\Facades\Log;
1011

1112
class DeviceController extends FleetOpsController
1213
{
@@ -64,11 +65,30 @@ public function attach(Request $request, string $id): JsonResponse
6465
'vehicle' => 'required_without:attachable_uuid|nullable|string',
6566
]);
6667

67-
$device = $this->findDevice($id);
68-
$vehicle = $this->findVehicle($request->input('vehicle') ?? $request->input('attachable_uuid'));
68+
$vehicleId = $request->input('vehicle') ?? $request->input('attachable_uuid');
69+
$device = $this->resolveDevice($id);
70+
$vehicle = $this->resolveVehicle($vehicleId);
6971

70-
$device->attachTo($vehicle);
71-
$device->load(['telematic', 'warranty', 'attachable']);
72+
if (!$device) {
73+
$this->logDeviceAttachmentLookupFailure('attach', 'device', $id, $vehicleId);
74+
75+
return response()->error('Device not found or not available for this organization.', 404);
76+
}
77+
78+
if (!$vehicle) {
79+
$this->logDeviceAttachmentLookupFailure('attach', 'vehicle', $id, $vehicleId);
80+
81+
return response()->error('Vehicle not found or not available for this organization.', 404);
82+
}
83+
84+
try {
85+
$device->attachTo($vehicle);
86+
$device->load(['telematic', 'warranty', 'attachable']);
87+
} catch (\Throwable $e) {
88+
$this->logDeviceAttachmentFailure('attach', $device, $vehicle, $e);
89+
90+
return response()->error('Unable to attach device to vehicle. Please try again or contact support.', 500);
91+
}
7292

7393
return response()->json([
7494
'status' => 'ok',
@@ -81,31 +101,75 @@ public function attach(Request $request, string $id): JsonResponse
81101
*/
82102
public function detach(string $id): JsonResponse
83103
{
84-
$device = $this->findDevice($id);
85-
$device->detach();
86-
$device->load(['telematic', 'warranty', 'attachable']);
104+
$device = $this->resolveDevice($id);
105+
106+
if (!$device) {
107+
$this->logDeviceAttachmentLookupFailure('detach', 'device', $id, null);
108+
109+
return response()->error('Device not found or not available for this organization.', 404);
110+
}
111+
112+
try {
113+
$device->detach();
114+
$device->load(['telematic', 'warranty', 'attachable']);
115+
} catch (\Throwable $e) {
116+
$this->logDeviceAttachmentFailure('detach', $device, null, $e);
117+
118+
return response()->error('Unable to detach device from vehicle. Please try again or contact support.', 500);
119+
}
87120

88121
return response()->json([
89122
'status' => 'ok',
90123
'device' => $device,
91124
]);
92125
}
93126

94-
protected function findDevice(string $id): Device
127+
protected function resolveDevice(string $id): ?Device
95128
{
96129
return Device::where(function ($query) use ($id) {
97130
$query->where('uuid', $id)->orWhere('public_id', $id);
98131
})
99132
->where('company_uuid', session('company'))
100-
->firstOrFail();
133+
->first();
101134
}
102135

103-
protected function findVehicle(?string $id): Vehicle
136+
protected function resolveVehicle(?string $id): ?Vehicle
104137
{
138+
if (!$id) {
139+
return null;
140+
}
141+
105142
return Vehicle::where(function ($query) use ($id) {
106143
$query->where('uuid', $id)->orWhere('public_id', $id);
107144
})
108145
->where('company_uuid', session('company'))
109-
->firstOrFail();
146+
->first();
147+
}
148+
149+
protected function logDeviceAttachmentLookupFailure(string $action, string $missingResource, string $deviceId, ?string $vehicleId): void
150+
{
151+
Log::warning('Device attachment lookup failed', [
152+
'action' => $action,
153+
'missing_resource' => $missingResource,
154+
'device_id' => $deviceId,
155+
'vehicle_id' => $vehicleId,
156+
'company_uuid' => session('company'),
157+
'request_id' => request()->headers->get('X-Request-ID') ?? request()->headers->get('X-Correlation-ID'),
158+
]);
159+
}
160+
161+
protected function logDeviceAttachmentFailure(string $action, Device $device, ?Vehicle $vehicle, \Throwable $exception): void
162+
{
163+
Log::error('Device attachment failed', [
164+
'action' => $action,
165+
'device_uuid' => $device->uuid,
166+
'device_id' => $device->public_id,
167+
'vehicle_uuid' => $vehicle?->uuid,
168+
'vehicle_id' => $vehicle?->public_id,
169+
'company_uuid' => session('company'),
170+
'request_id' => request()->headers->get('X-Request-ID') ?? request()->headers->get('X-Correlation-ID'),
171+
'exception_class' => get_class($exception),
172+
'exception' => $exception->getMessage(),
173+
]);
110174
}
111175
}

‎server/src/Http/Controllers/Internal/v1/TelematicController.php‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ public function discover(Request $request, string $id): JsonResponse
110110
$telematic = $this->findTelematic($id);
111111

112112
$jobId = $this->telematicService->discoverDevices($telematic, [
113-
'limit' => $request->input('limit', 100),
113+
'limit' => $request->input('limit'),
114114
'filters' => $request->input('filters', []),
115115
]);
116116

‎server/src/Http/Controllers/Internal/v1/VehicleController.php‎

Lines changed: 94 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Illuminate\Http\Request;
1717
use Illuminate\Support\Arr;
1818
use Illuminate\Support\Facades\DB;
19+
use Illuminate\Support\Facades\Log;
1920
use Illuminate\Support\Str;
2021
use Maatwebsite\Excel\Facades\Excel;
2122

@@ -179,12 +180,31 @@ public function attachDevice(Request $request, string $id): JsonResponse
179180
{
180181
$request->validate(['device' => 'required|string']);
181182

182-
$vehicle = $this->findVehicle($id);
183-
$device = $this->findDevice($request->input('device'));
183+
$deviceId = $request->input('device');
184+
$vehicle = $this->resolveVehicle($id);
185+
$device = $this->resolveDevice($deviceId);
184186

185-
$device->attachTo($vehicle);
186-
$device->load(['telematic', 'warranty', 'attachable']);
187-
$vehicle->load(['driver', 'devices']);
187+
if (!$vehicle) {
188+
$this->logDeviceAttachmentLookupFailure('attach-device', 'vehicle', $id, $deviceId);
189+
190+
return response()->error('Vehicle not found or not available for this organization.', 404);
191+
}
192+
193+
if (!$device) {
194+
$this->logDeviceAttachmentLookupFailure('attach-device', 'device', $id, $deviceId);
195+
196+
return response()->error('Device not found or not available for this organization.', 404);
197+
}
198+
199+
try {
200+
$device->attachTo($vehicle);
201+
$device->load(['telematic', 'warranty', 'attachable']);
202+
$vehicle->load(['driver', 'devices']);
203+
} catch (\Throwable $e) {
204+
$this->logDeviceAttachmentFailure('attach-device', $vehicle, $device, $e);
205+
206+
return response()->error('Unable to attach device to vehicle. Please try again or contact support.', 500);
207+
}
188208

189209
return response()->json([
190210
'status' => 'ok',
@@ -198,16 +218,35 @@ public function detachDevice(Request $request, string $id): JsonResponse
198218
{
199219
$request->validate(['device' => 'required|string']);
200220

201-
$vehicle = $this->findVehicle($id);
202-
$device = $this->findDevice($request->input('device'));
221+
$deviceId = $request->input('device');
222+
$vehicle = $this->resolveVehicle($id);
223+
$device = $this->resolveDevice($deviceId);
224+
225+
if (!$vehicle) {
226+
$this->logDeviceAttachmentLookupFailure('detach-device', 'vehicle', $id, $deviceId);
227+
228+
return response()->error('Vehicle not found or not available for this organization.', 404);
229+
}
230+
231+
if (!$device) {
232+
$this->logDeviceAttachmentLookupFailure('detach-device', 'device', $id, $deviceId);
233+
234+
return response()->error('Device not found or not available for this organization.', 404);
235+
}
203236

204237
if ($device->attachable_uuid !== $vehicle->uuid) {
205238
return response()->error('This device is not attached to the selected vehicle.');
206239
}
207240

208-
$device->detach();
209-
$device->load(['telematic', 'warranty', 'attachable']);
210-
$vehicle->load(['driver', 'devices']);
241+
try {
242+
$device->detach();
243+
$device->load(['telematic', 'warranty', 'attachable']);
244+
$vehicle->load(['driver', 'devices']);
245+
} catch (\Throwable $e) {
246+
$this->logDeviceAttachmentFailure('detach-device', $vehicle, $device, $e);
247+
248+
return response()->error('Unable to detach device from vehicle. Please try again or contact support.', 500);
249+
}
211250

212251
return response()->json([
213252
'status' => 'ok',
@@ -226,6 +265,15 @@ protected function findVehicle(string $id): Vehicle
226265
->firstOrFail();
227266
}
228267

268+
protected function resolveVehicle(string $id): ?Vehicle
269+
{
270+
return Vehicle::where(function ($query) use ($id) {
271+
$query->where('uuid', $id)->orWhere('public_id', $id);
272+
})
273+
->where('company_uuid', session('company'))
274+
->first();
275+
}
276+
229277
protected function findDriver(string $id): Driver
230278
{
231279
return Driver::where(function ($query) use ($id) {
@@ -235,6 +283,42 @@ protected function findDriver(string $id): Driver
235283
->firstOrFail();
236284
}
237285

286+
protected function resolveDevice(string $id): ?Device
287+
{
288+
return Device::where(function ($query) use ($id) {
289+
$query->where('uuid', $id)->orWhere('public_id', $id);
290+
})
291+
->where('company_uuid', session('company'))
292+
->first();
293+
}
294+
295+
protected function logDeviceAttachmentLookupFailure(string $action, string $missingResource, string $vehicleId, ?string $deviceId): void
296+
{
297+
Log::warning('Vehicle device attachment lookup failed', [
298+
'action' => $action,
299+
'missing_resource' => $missingResource,
300+
'vehicle_id' => $vehicleId,
301+
'device_id' => $deviceId,
302+
'company_uuid' => session('company'),
303+
'request_id' => request()->headers->get('X-Request-ID') ?? request()->headers->get('X-Correlation-ID'),
304+
]);
305+
}
306+
307+
protected function logDeviceAttachmentFailure(string $action, Vehicle $vehicle, Device $device, \Throwable $exception): void
308+
{
309+
Log::error('Vehicle device attachment failed', [
310+
'action' => $action,
311+
'vehicle_uuid' => $vehicle->uuid,
312+
'vehicle_id' => $vehicle->public_id,
313+
'device_uuid' => $device->uuid,
314+
'device_id' => $device->public_id,
315+
'company_uuid' => session('company'),
316+
'request_id' => request()->headers->get('X-Request-ID') ?? request()->headers->get('X-Correlation-ID'),
317+
'exception_class' => get_class($exception),
318+
'exception' => $exception->getMessage(),
319+
]);
320+
}
321+
238322
protected function activeOrderUuid(Vehicle $vehicle): ?string
239323
{
240324
$vehicle->loadMissing('driver.currentOrder');

0 commit comments

Comments
 (0)